LoginSignup
3

More than 5 years have passed since last update.

Windows Installer手引書 Part.5 ファイル拡張子の関連付け

Last updated at Posted at 2018-11-06

前の記事へ  目次へ  次の記事へ

ファイル拡張子の関連付け

インストーラーで最もよく使われるレジストリは、ファイル拡張子の関連付けではないかと思います。

基本

プログラムをインストールする際、そのプログラムのデータファイルをダブルクリックしたときにプログラムを起動してデータを読ませるよう設定する、という要求はよくあります。関連付けはレジストリに書き込みます。例えば、プログラムyourapp.exeが拡張子.papaというデータファイルを使用するなら、次のようになります。

HKEY_CLASSES_ROOT
 + .papa
 |  + (Default) = YourProgID
 + YourProgID
 |  + shell
 |     + open
 |        + command
 |           + (Default) = "fullpath\yourapp.exe" "%1"

ここで、YourProgID[Vendor or Application].[Component].[Version]といった形式が推奨されています。全体的な情報は、Application RegistrationFile Typesあたりから読み進めていけば一通り得られます。例えばWiXでは、下記のようなソースで表現できます。このコードで、プログラムprTxtAのデータファイルとして、拡張子.papaのファイルを関連付けます。

 1: <?define prgid="prTxtA.extcmd.1"?>
 2: 
 3: <Component Id="prgCompo" Guid="956fe4e0-24eb-4e2f-89c4-18fd051f216e">
 4:   <File Id="prTxExeFile" KeyPath="yes" Source="..\prTxtA_SRC\prTxtA.exe" />
 5:   <RegistryValue Id="extRegv" Root="HKCR" Key=".papa" Type="string" Value="$(var.prgid)" />
 6:   <RegistryValue Id="comRegv" Root="HKCR" Key="$(var.prgid)\shell\open\command" Type="string" Value="&quot;[#prTxExeFile]&quot; &quot;%1&quot;" />
 7:              :
 8:              :
 9: </Component>

基本はこれで良いのですが、ちょっとした落とし穴があります。

他のアプリと利用する拡張子がかぶる

よく使われるメジャーなデータ形式は色々なアプリが拡張子の関連付けを奪い合います。また、同じアプリの異なるバージョンを一つのPCで利用できるケースもあり、どのように拡張子の関連付けを管理していくか悩むところです。先の基本で例示したレジストリ構造を見れば分かるように、何も考えずにすでに関連付け済みの拡張子に関連付けをすると、古い関連付けの情報は消えてしまいます。そこでまず、この部分

HKEY_CLASSES_ROOT
 + .papa
 |  + (Default) = YourProgID

アンインストール時に削除しないことが推奨されています

さらにWindowsには、ファイルアイコンを右クリックするとメニューに現れる「プログラムから開く」や、「ファイルの種類ごとに既定のアプリを選ぶ」機能があります。ここにインストールしたアプリを一覧表示させることで、容易にユーザーが拡張子の関連付けを変更できるようになります。下記のように、拡張子のキーの下にOpenWithProgidsキーを置くことで実現します。これは、prTxtAとprTxtBの2つのアプリをインストールした後の状態を示します。

HKEY_CLASSES_ROOT
 + .papa
 |  + (Default) = prTxtB.extcmd.1
 |  + OpenWithProgids
 |     + prTxtA.extcmd.1 = ""
 |     + prTxtB.extcmd.1 = ""
 + prTxtA.extcmd.1
 |  + shell
 |     + open
 |        + command
 |           + (Default) = "fullpath\prTxtA.exe" "%1"
 + prTxtB.extcmd.1
 |  + shell
 |     + open
 |        + command
 |           + (Default) = "fullpath\prTxtB.exe" "%1"

こうすると一覧から自分のアプリを容易に選べるようになります。
Part5Fig01.png

削除されないレジストリ(やファイル)をインストールする最も簡単な方法はComponentにPermanent属性を付けることでしょう。下記のソースのように削除しないレジストリを別のComponentに切り出せば実現できます。アンインストールすると実体のないProgIDが残ることになりますが、ProgIDが登録されていない場合は無視されるので問題ありません。ただし気を付けなければいけないのは、ComponentにPermanent属性を付けると、アンインストールしても環境にComponentの登録情報が残ることです。インストーラーのテストの都合でComponentの登録情報を削除する場合は、手動でレジストリから情報を消す必要があります。

 1: <?define prgid="prTxtA.extcmd.1"?>
 2: 
 3: <Component Id ="extCompo" Permanent="yes" Guid="bcadce47-ae51-4ad1-9391-227c998dea85">
 4:   <RegistryValue Id="extReg"      Root="HKCR" Key=".papa"                           Type="string" Value="$(var.prgid)" KeyPath="yes" />
 5: </Component>
 6: <Component Id="prgCompo" Guid="a5c70bd9-9158-4c0c-b8f4-4376bbc6e1fb">
 7:   <File Id="prTxExeFile" KeyPath="yes" Source="..\prTxtA_SRC\prTxtA.exe" />
 8:   <RegistryValue Id="openwithReg" Root="HKCR" Key=".papa\OpenWithProgids"           Type="string" Name="$(var.prgid)" Value="" />
 9:   <RegistryValue Id="comRegv"     Root="HKCR" Key="$(var.prgid)\shell\open\command" Type="string" Value="&quot;[#prTxExeFile]&quot; &quot;%1&quot;" />
10:              :
11:              :
12: </Component>

アイコン画像をデータファイルに割り当てる

MSDN Libraryの情報では、Programmatic Identifiersが参考になります。

  • アイコンファイルに割り当てる場合

progIDのキーの下にDefaultIconキーを置き、下記のようにアイコンファイルへのパスを記述します。

HKEY_CLASSES_ROOT
 + YourProgID
 |  + DefaultIcon
 |     + (Default) = fullpath\blueData.ico

WiXのソースは、例えば下記のようになります。

 1: <?define prgid="prTxtA.extcmd.1"?>
 2: 
 3: <Component Id="prgCompo" Guid="a5c70bd9-9158-4c0c-b8f4-4376bbc6e1fb">
 4:              :
 5:              :
 6:   <File Id="iconFile" Source="blueData.ico" />
 7:   <RegistryValue Id="iconReg" Root="HKCR" Key="$(var.prgid)\DefaultIcon" Type="string" Value="&quot;[$prgCompo]\blueData.ico&quot;" />
 8: </Component>
  • EXE,DLLのリソース中にあるアイコン画像を使う場合

ファイル名の後に何番目(0が1番目)のアイコンか指定します。例えば、リソースの2番目のアイコン画像を使うなら、次のようになります(DLLの場合も同じ書式です)。

HKEY_CLASSES_ROOT
 + YourProgID
 |  + DefaultIcon
 |     + (Default) = fullpath\prTxtA.exe,1

WiXのソースは、例えば下記のようになります。

 1: <?define prgid="prTxtA.extcmd.1"?>
 2: 
 3: <Component Id="prgCompo" Guid="387e3686-06e3-4cdf-9992-9c8ea7da56bc">
 4:              :
 5:              :
 6:   <File Id="prTxExeFile" KeyPath="yes" Source="..\prTxtA_SRC\prTxtA.exe" />
 7:   <RegistryValue Id="iconReg" Root="HKCR" Key="$(var.prgid)\DefaultIcon" Type="string" Value="[$prgCompo]\prTxtA.exe,1" />
 8: </Component>

[#prTxExeFile]や[$prgCompo]などの表現の意味

これまで何の説明もなくWiXのソースに使ってきましたが、これらはMSIの機能です。[#prTxExeFile]は、prTxExeFileというIdで定義したファイルへのフルパスを示します。[$prgCompo]は、prgCompoというIdで定義したコンポーネントのフォルダ・パスを示します。これらはインストールの実行時に値が入れられるのでパスをハード・コーディングするよりは良い方法です。

パスを表現する方法

環境変数を使ってパスを指し示す方法もあります。

前の記事へ  目次へ  次の記事へ

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3