WiX Toolset – CustomActionの組込

ユーザにプロダクトキーの入力を求め、正当性を検査するダイアログUserRegistrationDlgを作成します。

出来上がりは次のような画面です。

コードは次の通りです。プログラミングの経験がある人は、何をしているか見当がつくと思います。ただし、InvalidPidDlgは不正入力があったときの画面です。

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
 <Fragment>
  <!-- TODO: Put your code here. -->
    <UI>
      <Dialog Id="UserRegistrationDlg" Width="370" Height="270" Title="[ProductName] [Setup]" NoMinimize="yes">
        <Control Id="NameLabel" Type="Text" X="45" Y="73" Width="100" Height="15" TabSkip="no" Text="ユーザー名(&amp;U):" />
        <Control Id="NameEdit" Type="Edit" X="45" Y="85" Width="220" Height="18" Property="USERNAME" Text="{80}" />
        <Control Id="OrganizationLabel" Type="Text" X="45" Y="110" Width="100" Height="15" TabSkip="no" Text="会社名(&amp;O):" />
        <Control Id="OrganizationEdit" Type="Edit" X="45" Y="122" Width="220" Height="18" Property="COMPANYNAME" Text="{80}" />
        <Control Id="CDKeyLabel" Type="Text" X="45" Y="147" Width="50" Height="10" TabSkip="no">
          <Text>CD キー(&amp;K)</Text>
        </Control>
        <Control Id="CDKeyEdit" Type="MaskedEdit" X="45" Y="159" Width="250" Height="16" Property="PIDKEY" Text="[PIDTemplate]" />
        <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="戻る(&amp;B)">
          <Publish Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
        </Control>
        <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="次へ(&amp;N)">
          <Publish Event="DoAction" Value="CheckingPID" Order="1">1</Publish>
          <Publish Event="SpawnWaitDialog" Value="InvalidPidDlg" Order="2"><![CDATA[PIDACCEPTED = "1"]]></Publish>
          <Publish Event="NewDialog" Value="SetupTypeDlg" Order="3"><![CDATA[PIDACCEPTED = "1"]]></Publish>
        </Control>
        <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="キャンセル">
          <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
        </Control>
        <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
        <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
          <Text>あなたのユーザー情報を入力して下さい。</Text>
        </Control>
        <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
        <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
          <Text>{WixUI_Font_Title}ユーザー情報</Text>
        </Control>
        <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
      </Dialog>
      <Dialog Id="InvalidPidDlg" Width="260" Height="85" Title="[ProductName] [Setup]" NoMinimize="yes">
        <Control Id="Icon" Type="Icon" X="15" Y="15" Width="24" Height="24"
                 ToolTip="Information icon" FixedSize="yes" IconSize="32" Text="Exclam.ico" />
        <Control Id="Return" Type="PushButton" X="100" Y="57" Width="56" Height="17"
                 Default="yes" Cancel="yes" Text="戻る(&amp;R)">
          <Publish Event="EndDialog" Value="Return">1</Publish>
        </Control>
        <Control Id="Text" Type="Text" X="48" Y="15" Width="194" Height="30" TabSkip="no">
          <Text>入力されたユーザー・キーは無効です。弊社発行のキーを入力してください。</Text>
        </Control>
      </Dialog>
    </UI>
  </Fragment>
</Wix>

ここで注目していただきたいのは、15行目の[Back]PushButtonと18行目の[Next]PushButtonです。これらの[Control]要素の中にある [Publish]要素は、例えばBackコントロールでいえば、このボタンを押せば、新しいダイアログLicenseAgreementDlgに遷移しろという意味です。

[Next]ボタンを押したら、まず前回ご説明したCheckingPIDを実行しろ、その結果[PIDACCEPTED = 1](キー正常)でなければInvalidPidDlgに遷移しろ、[PIDACCEPTED = 1]ならばSetupTypeDlg画面に遷移しろ、ということになります。

20行目、SpawnWaitDialogは条件が「偽」の場合、Value=”InvalidPidDlg”に遷移しろ、という命令です。注意してください。

さて、このダイアログ・コードをメインプログラムに組み込む方法は二つあります。

一つは本体に対してライブラリー・プロジェクトを作成する方法です。VSのWindows Installer XMLからSetup Library Projectを選択して新規のプロジェクトを作成し、メインプロジェクトからは、他のライブラリー同様参照設定して使用します。

もう一つは、単純にメインプロジェクトに、WiXファイルを新規に追加して、メインプロジェクトの一ファイルとして開発します。

コードは全く同じですから、セットアップ・プロジェクトが大規模かどうか等で選択すればいいと思います。

さて、カスタムアクションと特注のダイアログをどのようにメインコードに組み込むか。

最初はカスタムアクションの定義です。

前々回ご紹介したカスタムアクションをビルドすると、ライブラリーCheckPID.CA.dllが得られます。メイン・プログラムの[Product]要素の直下に以下の文を挿入します。

<Binary Id="MyCustomActionDLL" SourceFile=".CheckPID.CA.dll" />
<CustomAction Id="CheckingPID" BinaryKey="MyCustomActionDLL" DllEntry="CheckPID" Execute="immediate" Return="check" />

少しご説明します。まず[Binary]要素を定義します。SourceFileはセットアップ・プロジェクト開発環境にあるカスタム・アクションのパス付ファイル名を指定します。

次はCustomAction の定義です。BinaryKeyはBinary要素のIdです。DllEntryはライブラリーCheckPID.CA.dllのエントリー関数名です。CustomActionのIdは、上にご紹介したUserRegistrationDlgのNextボタンで起動される、セットアッププロジェクトで使われるCustomAction の一意名です。

次はダイアログの組み込みです。同じくメイン・プログラムのProduct要素の直下に以下の文を挿入します。

まず、ユーザ定義のUI・MyWixUI_Mondoを宣言します。

この中で、WixUI_MondoとWixUI_ErrorProgressTextへの参照を宣言。続いて自作のUserRegistrationDlgを参照。次の「LicenseAgreementDlgの[Next]ボタンが押されたら、新しいダイアログUserRegistrationDlgに遷移しろ」、と「SetupTypeDlgダイアログでBackが押されたら、UserRegistrationDlgダイアログに遷移しろ」
を付け加えます。

    <UI Id="MyWixUI_Mondo">
      <UIRef Id="WixUI_Mondo" />
      <UIRef Id="WixUI_ErrorProgressText" />
      <DialogRef Id="UserRegistrationDlg" />
      <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="UserRegistrationDlg" Order="2">
        LicenseAccepted = "1"
      </Publish>
      <Publish Dialog="SetupTypeDlg" Control="Back" Event="NewDialog" Value="UserRegistrationDlg">
        1
      </Publish>
    </UI>

そのほか、アイコン指定や、グローバル変数(WiXではプロパティといいます)を定義します。以下、カスタムアクション関連のコードを再掲載します。

この中で、PIDTemplateはプロダクトキー入力用MaskedEditのテンプレートで、ここに入力された文字列からPIDKEYの値を取得します。

一番下の[WixVariable Id=”WixUILicenseRtf”] は使用許諾書の設定、
[WixVariable Id=”WixUIBannerBmp” ]はセットアップ画面に使う画像を指定しています。

<Binary Id="Exclam.ico" SourceFile="$(var.ImageFilesPath)warning.ico" />
<Property Id="PIDTemplate"><![CDATA[12345<^^^^ ^^^^ ^^^^ ^^^^>@@@@@]]></Property>
<Property Id="PIDACCEPTED" Value="123" />
<Binary Id="MyCustomActionDLL" SourceFile=".CheckPID.CA.dll" />
<CustomAction Id="CheckingPID" BinaryKey="MyCustomActionDLL" DllEntry="CheckPID" Execute="immediate" Return="check" />
<UI Id="MyWixUI_Mondo">
  <UIRef Id="WixUI_Mondo" />
  <UIRef Id="WixUI_ErrorProgressText" />
  <DialogRef Id="UserRegistrationDlg" />
  <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="UserRegistrationDlg" Order="2">
   LicenseAccepted = "1"
  </Publish>
  <Publish Dialog="SetupTypeDlg" Control="Back" Event="NewDialog" Value="UserRegistrationDlg">
   1
  </Publish>
</UI>
<WixVariable Id="WixUILicenseRtf" Value=".使用許諾契約書.rtf" />
<WixVariable Id="WixUIBannerBmp" Value="$(var.ImageFilesPath)myImage.bmp" />
error: コピーできません !!