1

一部の構成 xml ファイルに暗号化されたフィールドを含む製品を展開しています。インストール中に、ターゲット マシンで自己署名証明書を作成しています。次に、それを使用していくつかの文字列を暗号化し、最後にそれらを構成ファイルに保存する必要があります。

証明書を作成するために、ターゲット インストール ディレクトリにmakecert.exeを持ってきます。そのため、証明書を作成する CustomAction を実行する前に、すべてのファイルが宛先にコピーされるまで待つ必要があります。この後、他のいくつかの CustomAction が、構成に保存する必要がある暗号化された値を作成しています。

これはうまく機能しますが、この時点で構成ファイルに新しい値を保存したいと考えていますが、XmlFile/XmlConfig が実行された段階を既に見逃しています。MSI ログを見ると、ファイルがコピーされた直後に「ExecXmlConfig」アクションが実行されていることがわかります。

MSI (s) (6C:CC) [02:12:10:898]: Source for file 'makecert.exe' is compressed
InstallFiles: File: makecert.exe,  Directory: C:\Program Files (x86)\MyProduct\InstanceFolder\,  Size: 60240
MSI (s) (6C:CC) [02:12:10:900]: Executing op: SetTargetFolder(Folder=C:\Program Files (x86)\MyProduct\Nhibernate\)
MSI (s) (6C:CC) [02:12:10:900]: Executing op: SetSourceFolder(Folder=1\o1lebnnf\vemzkq_g\|MyProduct\Nhibernate\)
MSI (s) (6C:CC) [02:12:10:901]: Executing op: FileCopy(SourceName=nw4bpvhi.xml|hibernate.cfg.xml,SourceCabKey=nhibernate.config,DestName=hibernate.cfg.xml,....
MSI (s) (6C:CC) [02:12:10:902]: File: C:\Program Files (x86)\MyProduct\Nhibernate\hibernate.cfg.xml;    Won't Overwrite;    Won't patch;    Existing file is unversioned but modified
MSI (s) (6C:CC) [02:12:10:902]: Executing op: SetTargetFolder(Folder=C:\Program Files (x86)\MyProduct\InstanceFolder\)
MSI (s) (6C:CC) [02:12:10:902]: Executing op: SetSourceFolder(Folder=1\o1lebnnf\|MyProduct\)
MSI (s) (6C:CC) [02:12:10:902]: Executing op: FileCopy(SourceName=7z64.dll,SourceCabKey=Seven7z64.dll,DestName=7z64.dll,Attributes=512,...
MSI (s) (6C:CC) [02:12:10:903]: File: C:\Program Files (x86)\MyProduct\InstanceFolder\7z64.dll; To be installed;    Won't patch;    No existing file
MSI (s) (6C:CC) [02:12:10:903]: Source for file 'Seven7z64.dll' is compressed
InstallFiles: File: 7z64.dll,  Directory: C:\Program Files (x86)\MyProduct\InstanceFolder\,  Size: 1484800
MSI (s) (6C:CC) [02:12:10:929]: Executing op: CacheSizeFlush(,)
MSI (s) (6C:CC) [02:12:10:929]: Executing op: ActionStart(Name=ExecXmlConfigRollback,,)
Action 02:12:10: ExecXmlConfigRollback. 
MSI (s) (6C:CC) [02:12:10:948]: Executing op: CustomActionSchedule(Action=ExecXmlConfigRollback,ActionType=3329,Source=BinaryData,Target=ExecXmlConfigRollback,...
MSI (s) (6C:CC) [02:12:10:949]: Executing op: ActionStart(Name=ExecXmlConfig,,)
Action 02:12:10: ExecXmlConfig. 
MSI (s) (6C:CC) [02:12:10:951]: Executing op: CustomActionSchedule(Action=ExecXmlConfig,ActionType=3073,Source=BinaryData,Target=ExecXmlConfig,CustomActionData=1?C:\Program Files (x86)\MyProduct\Nhibernate\hibernate.cfg.xml?3?0?/hibernate-configuration/session-factory/property[@name='connection.connection_string']????0)

だから私は間に詰まっています...実行するように CustomAction を構成するAfter='InstallFiles'と、ファイルがコピーされるずっと前に実行しようとします。(正しいイベントがありませんか?)。一方、アクションを実行するように構成するとAfter='InstallFinalize'、XmlConfig が既に起動され、構成ファイルに何も書き込まれていないため、遅すぎます。理想的には、インストールの最後にこれらすべてを実行したいと考えています。

ExecXmlConfig とまったく同じ操作を行う CustomAction を別のときに呼び出すために記述する必要があるのはばかげているようです...

これが私のInstallExecuteSequenceです:

    <InstallExecuteSequence>

      <!-- Create and Register Certificate on Install -->
      <Custom Action='GenerateProductCertificate'         After='InstallFiles'><![CDATA[REMOVE<>"ALL"]]></Custom>
      <Custom Action='RegisterProductServiceCertificate'  After='GenerateProductCertificate'><![CDATA[REMOVE<>"ALL"]]></Custom>

      <!-- Create and NHibernate Certificate -->      
      <Custom Action='GenerateNHibernateCertificate'      After='RegisterProductServiceCertificate'><![CDATA[REMOVE<>"ALL"]]></Custom>

      <!-- Configure NHibernate XML with Encrypted ConnectionString -->
      <Custom Action='GenerateSecureConnectionString'                   After='GenerateNHibernateCertificate'><![CDATA[(REMOVE<>"ALL")]]></Custom>

  </InstallExecuteSequence>

WiX 3.7 (v3.7.1022.0、2012 年 10 月 22 日月曜日) を使用しています。

私の質問は次のとおりです。

  • ExecXmlConfig アクションを CustomActions の後に実行するように再スケジュールする方法はありますか?
  • そうでない場合、ファイルのコピーと ExceXmlConfig の間に CustomActions を実行するようにスケジュールできますか?

編集:

さらに数回試行し、もう少し調査した後、問題をより正確に定義できます。私が知りたいのは、次の延期アクションで利用できる延期アクションからの出力値を設定する方法です。

私のシナリオでは、カスタム アクションを遅延モードで実行する必要があるため、セッションにアクセスして新しい変数を保存することはできません。しかし、より多くの延期されたアクションがスケジュールされていると確信しているので、私がやろうとしているのは、いくつかの変数をそれらに渡す方法を見つけることです。

4

1 に答える 1

1

私が現在構築しているmsiでも同じ疑問が生じました。

次の据え置きアクションで使用できる据え置きアクションからの出力値を設定する方法は?

肝心なのは、これを正確に行うことができなかったということです。ただし、追加のカスタム アクションを使用して回避する方法を見つけました。

私の状況は少し異なりますが、うまくいけば役に立ちます。この場合、更新する必要があるいくつかのレジストリ エントリがあり、ロールバックの場合に備えて以前の値を保存したいと考えています。値の名前はインストールに依存するため、標準の msi レジストリ メカニズムを使用できません (可能な値の範囲は知っています)。

私のカスタム アクションは、バイナリ dll 内の C++ ベースのコードです。私が最初に考えたのは、DLL が読み込まれるとそのまま残り、遅延実行シーケンス内のすべての呼び出しが、作成されたデータ構造にアクセスできるという仮定に基づいていました。そこで、単純にグローバル変数を作成し、必要なデータをそこに保存しました。ただし、ロールバック呼び出し中、構造体は空でした。dll への各呼び出しの前に、dll がリロードされるようです。DllMainが複数回呼び出されていることを確認するために十分に調査しましたが、これを完全に確認したわけではありません。

私が最終的にたどり着いた解決策は、実行シーケンスのスクリプト生成ラウンドで実行される 2 つの追加のカスタム アクションを作成することでした。インストール用とロールバック用にそれぞれ 1 つずつです。彼らはレジストリをスキャンし、それぞれのインストールおよびロールバック カスタム アクションの CustomActionData として保存された区切り文字列を生成しました。作業が行われる遅延カスタム アクションは、CustomActionData を通じて指示されたことを実行するように書き直されました。すべての「ロジック」(ほぼすべて) は、区切り文字列を作成したコードにあります。

これはうまくいくようです。私が持っている唯一のわずかな懸念は、レジストリのスキャンとレジストリの更新の間に遅延と関連付けの解除があることです。美的な目的のために、これを回避しようとしていたと思います。

あなたのケースで同様のことができるかどうかはわかりません。考えられることの 1 つは、バイナリ dll を使用してすべての作業を管理することです。また、最初のカスタム アクションのシミュレートされた出力に基づいて CustomActionData を生成するカスタム アクションもあり、2 番目のカスタム アクションで読み取ることができます。カスタム アクションには外部 exe の呼び出しが含まれるため、ShellExecute、System、CreateProcess などで実行できます。問題は、最初のカスタム アクションを実際に実行しなくても、十分な情報を取得できるかどうかです。

于 2013-01-08T22:56:41.103 に答える