【问题标题】:MSI Log Debug Log SinkMSI 日志调试日志接收器
【发布时间】:2025-10-21 04:25:01
【问题描述】:

我有一个 InstallShield MSI 项目。当我将 MSIHANDLE 从 InstallScript 自定义操作传递到通过 DotNetCoCreateObject() 初始化的托管程序集时,我的托管代码中收到的值为 -2。

有谁知道是否可以从通过 DotNetCoCreateObject() 调用托管代码的 InstallScript 自定义操作访问 MSIHANDLE?我想将我的自定义操作结果记录到与安装的其余部分相同的日志文件中。我正在使用 InstallShield 2010、Windows Install 4.5 和 .Net 3.5。

【问题讨论】:

    标签: c# windows-installer installshield


    【解决方案1】:

    这只能通过托管自定义操作实现,并且需要使用 InstallShield 的 InstallShield.Interop.Msi.dll 来获取实际句柄。

    要从托管自定义操作写入 MSI 日志文件,此方法有效:

     using (Msi.Install msi = Msi.CustomActionHandle(_msiHandle))
     {
         using (Msi.Record record = new Msi.Record(100))
         {
             record.SetString(0, "LOG: [1]");
             record.SetString(1, entry.Message);
             msi.ProcessMessage(Msi.InstallMessage.Info, record);
         }
     }
    

    注意:自 IS2010 起,InstallShield.Interop.Msi.dll 未进行数字签名,因此包含托管自定义操作的程序集也必须未签名。

    【讨论】:

    • 要记住的另一件事是,这仅在未从控件事件的 DoAction 调用 CustomAction 时才有效。我有一个自定义操作,它使用这种方法将消息写入日志。为了测试这一点,我将操作附加到 UI 中的按钮按下,也作为 InstallExecuteSequence 中的操作。附加到 UI 的操作没有记录语句,而当作为 ExecuteSequence 的一部分运行相同的操作时,它会将其记录到日志中。
    • 显然,这是因为 MsiProcessMessage 在 DoAction 控制事件中不起作用。解决此问题的一种方法是使用要记录的消息设置属性。
    • 添加上述代码后,我在 MSI 日志中出现错误 ----- 调用目标引发了异常。 ---> System.IO.FileNotFoundException:无法加载文件或程序集“InstallShield.Interop.Msi,Version=23.0.0.511,Culture=neutral,PublicKeyToken=null”或其依赖项之一。该系统找不到指定的文件。 ---- 我将此 dll 添加到我的项目中,我可以在输出目录中看到,但是如何将 InstallShield.Interop.Msi dll 加载到安装程序中?
    • 我通过将 InstallShield.Interop.Msi dll 添加到直接编辑器的附加工具下的 ISCrWrap 表中解决了上述错误。该表有 3 列。第一列 -> 给出自定义操作名称,第二列“Dependecy0”第三列“\system\InstallShield.Interop.Msi.dll”
    【解决方案2】:

    不,这是不可能的。您必须自己管理日志输出。

    【讨论】:

      【解决方案3】:

      另一个澄清点是 IS 有两种项目类型,InstallScript 和 MSI。您只能在 MSI 项目中访问 MSI 句柄。

      【讨论】: