如何将 C# 方法添加到现有的大型 wix 脚本中

Dav*_*len 3 c# wix

我们现有的 wix 脚本相当复杂且冗长。所有自定义操作均使用内联 vbscript 执行。

我想将其中一些操作从 vbscript 切换到 C#。各地的所有示例都以“在 VisualStudio 中创建一个 wix 项目...”开头。有没有关于如何将 C# 代码添加到现有 wix 项目的示例?它是使用老式 wix 命令行应用程序构建的吗?

Ste*_*mul 6

先无耻地推广C++自定义动作!:-)。

还有:“WiX 快速入门”(一些指向良好 WiX 和 MSI 资源的指示)。


逐步:我会尝试一下,请尝试这个(如果您完成了这些初步步骤,您可能想跳到底部源代码 - 这是真正的一步一步,而且非常慢开始行动 - 您可能会直接从 WiX 源获得您需要的内容):

  1. 在 WiX Visual Studio 解决方案中,right click solution node at top=> Add=>New Project...

  2. 展开 WiX Toolset 节点,选择 v3(前提是您使用的 WiX 版本)

  3. 双击"C# Custom Action Project for WiX v3"

  4. 右键单击"References"WiX 项目(不在 C# 项目中)=>Add Reference...

  5. 去"Projects"添加一个引用C# project(双击并确定)

  6. 进行测试构建。如果之前没有错误的话,现在应该没有错误了。

  7. 您应该"CustomAction1.CA.dll"在构建输出窗口中看到类似的内容。该后缀*.CA.dll被添加到原始托管代码 dll 的 win32 包装 dll 中。所有这些都是由 WiX 本身处理的 - 或者实际上是 WiX 的 Votive Visual Studio 集成 - 只需知道其中的区别即可:

    • "CustomAction1.dll"- 托管代码 dll。
    • "CustomAction1.CA.dll"- 本机 win32 包装 dll 包含本机 1 和几个其他组件。Include this version in your MSI。
  8. 添加以下代码片段:

     <Binary Id="CustomActions" SourceFile="$(var.CustomAction1.TargetDir)\$(var.CustomAction1.TargetName).CA.dll" />
    
    Run Code Online (Sandbox Code Playgroud)
  9. 上面应该将实际的 C# dll 编译到 MSI 中。您可以在 Orca 中打开 MSI 并在二进制表中查看。

  10. 这不是很好,但我喜欢添加一个引用System.Windows.Forms并使用 aMessageBox.Show在自定义操作中显示一个对话框,以确保它按预期运行。我还为在调试模式下构建的 dll 添加了应用程序调试器启动命令。这样,Visual Studio 将被自动调用(如果一切正常),以便可以逐步执行代码。

  11. "System.Windows.Forms"通过右键单击 C# 项目的 Reference 节点来添加引用,然后添加"System.Windows.Forms". 还要添加"using System.Windows.Forms;"到源文件的顶部 - 请参阅下面的完整源代码。关键是要记住"System.Windows.Forms" 在项目级别进行引用。

  12. 现在将其作为测试代码添加到自定义操作项目的"CustomAction1"自定义操作代码片段中(有关完整源代码,请参阅底部的代码部分):

       // will launch the debugger for debug-build dlls
       #if DEBUG
         System.Diagnostics.Debugger.Launch();
       #endif
    
       MessageBox.Show("hello world");
    
    Run Code Online (Sandbox Code Playgroud)
  13. 要获得标准设置 GUI(对于阅读本文的其他人),请添加对此处所述的引用(这是创建可编译并具有 GUI 的基本 WiX 项目的分步指南),然后将其注入到您的来源:WiXUIExtension

     <UIRef Id="WixUI_Mondo" />
    
    Run Code Online (Sandbox Code Playgroud)
  14. 我喜欢更改<MediaTemplate />为<MediaTemplate EmbedCab="yes" />以避免外部源 cab 文件(通过此更改 cab 文件被编译到 MSI 中)。

  15. 如果您没有添加任何组件,您可以将其添加到notepad.exe您的 MSI 中,以便在目录下进行测试安装INSTALLFOLDER(只是在没有可用源文件的情况下安装某些组件的技巧 - 应该在任何计算机上解析的源路径) - 替换整个“TODO”部分 - 请参阅下面的完整源代码:

     <Component Feature="ProductFeature">
       <File Source="$(env.SystemRoot)\notepad.exe" />
     </Component>
    
    Run Code Online (Sandbox Code Playgroud)
  16. 现在我们需要声明实际的自定义操作并将其插入安装序列中。让我们将其添加到前面的下面<Binary> element:

     <CustomAction Id="CA1" BinaryKey="CustomActions" DllEntry="CustomAction1"/>
    
     <InstallUISequence>
       <Custom Action="CA1" After="CostFinalize" />
     </InstallUISequence>
    
     <InstallExecuteSequence>
       <Custom Action="CA1" After="CostFinalize" />
     </InstallExecuteSequence>
    
    Run Code Online (Sandbox Code Playgroud)
  17. 现在构建并测试运行 MSI。您应该会收到大量"hello world"消息。

  18. 这是 C#/托管代码自定义操作的整体"heartbeat"- 我有时使用它们的方式。


WiX Source Actual:现在,综合 -记得替换所有 GUID!:

构造:$(env.SystemRoot)- 在下面的 WiX 源代码中 - 获取环境变量%SystemRoot%- 在大多数系统上解析为 C:\(要列出环境变量,请打开 acmd.exe 并set键入并按Enter)。因此,以下源代码应在所有系统上编译而无需修改:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" Name="DemoCA" Language="1033" Version="1.0.0.0" Manufacturer="test" UpgradeCode="0adf972a-5562-4a6f-a552-dd1c16761c55">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <MediaTemplate EmbedCab="yes" />
    
    <UIRef Id="WixUI_Mondo" />

 <!-- START CUSTOM ACTION CONSTRUCTS -->
    
    <Binary Id="CustomActions" SourceFile="$(var.CustomAction1.TargetDir)\$(var.CustomAction1.TargetName).CA.dll" />

    <CustomAction Id="CA1" BinaryKey="CustomActions" DllEntry="CustomAction1"/>

    <InstallUISequence>
      <Custom Action="CA1" After="CostFinalize" />
    </InstallUISequence>

    <InstallExecuteSequence>
      <Custom Action="CA1" After="CostFinalize" />
    </InstallExecuteSequence>

 <!-- END CUSTOM ACTION CONSTRUCTS -->

    <Feature Id="ProductFeature" Title="AddingCSharpCustomActions" Level="1">
            <ComponentGroupRef Id="ProductComponents" />
        </Feature>
    </Product>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
               <Directory Id="INSTALLFOLDER" Name="AddingCSharpCustomActions"/>
            </Directory>
        </Directory>
    </Fragment>

    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">

         <Component Feature="ProductFeature">
           <File Source="$(env.SystemRoot)\notepad.exe" />
         </Component>

        </ComponentGroup>
    </Fragment>
</Wix>
Run Code Online (Sandbox Code Playgroud)

步骤简述:所需更改的简短摘要:

  1. 将制造商字段设置为某项。
  2. 如上所述添加和修改自定义操作构造。
  3. 将组件/文件元素添加到底部,替换那里的“TODO”部分。
  4. MediaTemplate如上所述设置为使用嵌入式驾驶室(可选,对于示例工作而言不是必需的)。

自定义操作代码:最后是实际的 C# 自定义操作测试代码 - 使用 Debugger.Launch 进行更新,它将启动调试构建 DLL 的调试器。然后,您可以将调试器附加到正确的源项目并单步执行代码:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Deployment.WindowsInstaller;
using System.Windows.Forms;

namespace CustomAction1
{
    public class CustomActions
    {
        [CustomAction]
        public static ActionResult CustomAction1(Session session)
        {

#if DEBUG
            System.Diagnostics.Debugger.Launch();
#endif

            MessageBox.Show("hello world");

            session.Log("Begin CustomAction1");

            return ActionResult.Success;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

链接: