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

How do I add C# methods to an existing large wix script(如何将 C# 方法添加到现有的大型 wix 脚本)
本文介绍了如何将 C# 方法添加到现有的大型 wix 脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个非常复杂的现有 wix 脚本 &长.所有的 CustomAction 都是使用内联 vbscript 执行的.

We have an existing wix script that is pretty complex & long. All the CustomActions are performed with inline vbscript.

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

I want to switch some of those actions from vbscript to C#. All the examples everywhere start with "create a wix project in VisualStudio...". Is there any example out there about how to add in C# code to an existing wix project? One where it is built using the old school wix command line apps?

推荐答案

无耻宣传C++自定义动作优先! :-).

并且:WiX 快速入门"(一些指向良好 WiX 和 MSI 资源的指针).

And: "WiX Quick Start" (some pointers to good WiX and MSI resources).


Step-By-Step:我会试一试,请试试这个(如果你已经完成了,你可能想跳到底部的源代码通过这些初步步骤 - 这是一步一步的实际操作,而且执行起来非常缓慢 - 您可能会直接从 WiX 源获得所需的内容):


Step-By-Step: I'll give it a try, please try this (you might want to skip to the bottom source if you are sort of done with these preliminary steps - this is step-by-step for real and very slow to get to the action - you might get what you need straight from the WiX source):

  1. 在 WiX Visual Studio 解决方案中,右键单击顶部的解决方案节点 =>添加 =>新建项目...

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

Expand WiX Toolset node, select v3 (provided that is the version of WiX you use)

双击C# Custom Action Project for WiX v3"

Double click "C# Custom Action Project for WiX v3"

在 WiX 项目中(不在 C# 项目中)右键单击 References" =>添加参考...

Right click "References" in WiX project (not in C# project) => Add Reference...

转到 Projects" 并添加对 C# 项目的引用(双击和好的)

Go "Projects" and add a reference to the C# project (double click and OK)

进行测试构建.前提是之前没有错误,现在应该没有.

Do a test build. Provided there were no errors before there should be none now.

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

You should see something like "CustomAction1.CA.dll" in the build Output window. The suffix *.CA.dll is added to a win32 wrapper dll for the original managed code dll. All of this is handled by WiX itself - or actually the Votive Visual Studio integration for WiX - just know the difference:

  • CustomAction1.dll" - 托管代码 dll.
  • CustomAction1.CA.dll" - 原生 win32 包装 dll,包含原生组件和其他几个组件.将此版本包含在您的 MSI 中.

添加以下代码段:

 <Binary Id="CustomActions" SourceFile="$(var.CustomAction1.TargetDir)$(var.CustomAction1.TargetName).CA.dll" />

  • 上面应该将实际的 C# dll 编译到 MSI 中.您可以在 Orca 中打开 MSI 并在二进制表中查看.

  • The above should compile the actual C# dll into the MSI. You can open the MSI in Orca and see in the Binary table.

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

    It is not great, but I like to add a reference to System.Windows.Forms and use a MessageBox.Show to show a dialog from within the custom action to ensure it is running as expected. I also add the application debugger launch command for dlls built in debug mode. That way Visual Studio will be automatically invoked (if all works correctly) so the code can be stepped through.

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

    Add the reference to "System.Windows.Forms" by right clicking the C# project's Reference node and then add "System.Windows.Forms". Also add "using System.Windows.Forms;" to the top of the source file - see full source below. The key is to remember to reference "System.Windows.Forms" at a project level.

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

    Now add this as test code to the custom action project's "CustomAction1" custom action code snippet (see code section towards bottom for full source):

       // will launch the debugger for debug-build dlls
       #if DEBUG
         System.Diagnostics.Debugger.Launch();
       #endif
    
       MessageBox.Show("hello world");
    

  • 要获得标准设置 GUI(对于阅读此内容的其他人),请添加对 WiXUIExtension 如此处所述(这是创建可编译并具有 GUI 的基本 WiX 项目的分步操作),然后将其注入您的源代码:

  • To get a standard setup GUI (for others who read this), add a reference to WiXUIExtension as explained here (that is a step-by-step for creating a basic WiX project that compiles and has a GUI), and then inject this into your source:

     <UIRef Id="WixUI_Mondo" />
    

  • 我喜欢将 <MediaTemplate/> 更改为 <MediaTemplate EmbedCab=yes"/> 避免使用外部源 cab 文件(通过此更改,cab 被编译到 MSI 中).

  • I like to change <MediaTemplate /> to <MediaTemplate EmbedCab="yes" /> to avoid external source cab files (with this change cabs are compiled into the MSI).

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

    If you don't have any components added, you can add this to include notepad.exe in your MSI for test installation under directory INSTALLFOLDER (just a trick to install something without having source files available - a source path that should resolve on any machine) - replace the whole "TODO" section - see full source below:

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

  • 现在我们需要声明实际的自定义操作并将其插入到安装序列中.让我们在前面的 <Binary> 下添加它.元素:

     <CustomAction Id="CA1" BinaryKey="CustomActions" DllEntry="CustomAction1"/>
    
     <InstallUISequence>
       <Custom Action="CA1" After="CostFinalize" />
     </InstallUISequence>
    
     <InstallExecuteSequence>
       <Custom Action="CA1" After="CostFinalize" />
     </InstallExecuteSequence>
    

  • 现在构建并测试运行 MSI.您应该会收到大量 hello world" 消息.

  • Now build and test run the MSI. You should get numerous "hello world" messages.

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

    That is the overall "heartbeat" of a C# / managed code custom action - the way I sometimes use them.


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

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

    The construct: $(env.SystemRoot) - in the WiX source below - gets the environment variable %SystemRoot% - which resolves to C: on most systems (to list environment variables open a cmd.exe and type set and press Enter). The below source should hence compile on all systems without modifications:

    <?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)
    otepad.exe" />
             </Component>
    
            </ComponentGroup>
        </Fragment>
    </Wix>
    

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

    Steps-in-brief: short summary of changes needed:

    1. 将制造商字段设置为某些内容.
    2. 如上所示添加和修改自定义操作结构.
    3. 向底部添加组件/文件元素,替换TODO"部分.
    4. 如上所述,将 MediaTemplate 设置为使用嵌入式 cab(可选,不是示例运行所必需的).


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


    Custom Action Code: And finally the actual C# custom action test code - updated with Debugger.Launch which will launch the debugger for a debug-build DLL. You can then attach the debugger to the correct source project and step-through the code:

    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;
            }
        }
    }
    


    链接:

    • 调试 MSI 自定义操作
    • C++ 自定义操作和常见问题
    • WiX 资源链接各种
    • 早先忘记了这个 - 更简单,可能更清晰
    • C# 自定义操作 - Windows 安装程序(高级安装程序视频)
    • Debugging MSI Custom Actions
    • C++ Custom Action and Common Problems
    • WiX resource links of all kinds
    • Forgot this one from earlier - simpler and might be clearer
    • C# custom actions - Windows Installer (Advanced Installer video)

    这篇关于如何将 C# 方法添加到现有的大型 wix 脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

  • 本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

    相关文档推荐

    DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
    Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
    Programmatically show the desktop(以编程方式显示桌面)
    c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
    InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
    LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)