c# - 如何将 C# 方法添加到现有的大型 wix 脚本
问题描述
我们有一个非常复杂且冗长的现有 wix 脚本。所有的 CustomAction 都是使用内联 vbscript 执行的。
我想将其中一些操作从 vbscript 切换到 C#。随处可见的所有示例都以“在 VisualStudio 中创建 wix 项目...”开头。有没有关于如何将 C# 代码添加到现有 wix 项目的示例?它是使用老式 wix 命令行应用程序构建的吗?
解决方案
先无耻地宣传C++自定义动作!:-)。
并且:“WiX 快速入门”(一些指向良好 WiX 和 MSI 资源的指针)。
一步一步:我会试一试,请试试这个(如果你已经完成了这些初步步骤,你可能想跳到底部的源代码 - 这是真正的一步一步,非常慢开始行动 - 你可能会直接从 WiX 源获得你需要的东西):
在 WiX Visual Studio 解决方案中,
right click solution node at top
=>Add
=>New Project...
展开 WiX Toolset 节点,选择 v3(前提是你使用的 WiX 版本)
双击
"C# Custom Action Project for WiX v3"
右键单击
"References"
WiX 项目(不在 C# 项目中)=>Add Reference...
去
"Projects"
添加一个引用C# project
(双击并确定)进行测试构建。前提是之前没有错误,现在应该没有。
"CustomAction1.CA.dll"
您应该会在构建输出窗口中看到类似的内容。后缀*.CA.dll
被添加到原始托管代码 dll 的 win32 包装器 dll 中。所有这些都由 WiX 本身处理 - 或者实际上是 WiX 的 Votive Visual Studio 集成 - 只知道区别:"CustomAction1.dll"
- 托管代码 dll。"CustomAction1.CA.dll"
- 本机 win32 包装 dll 包含本机一个和几个其他组件。Include this version in your MSI
.
添加以下代码段:
<Binary Id="CustomActions" SourceFile="$(var.CustomAction1.TargetDir)\$(var.CustomAction1.TargetName).CA.dll" />
以上应该将实际的 C# dll 编译到 MSI 中。您可以在 Orca 中打开 MSI 并在二进制表中查看。
这不是很好,但我喜欢添加一个引用
System.Windows.Forms
并使用 aMessageBox.Show
从自定义操作中显示一个对话框,以确保它按预期运行。我还为在调试模式下构建的 dll 添加了应用程序调试器启动命令。这样,Visual Studio 将被自动调用(如果一切正常),因此可以单步执行代码。通过右键单击 C# 项目的 Reference 节点添加对
"System.Windows.Forms"
的引用,然后添加"System.Windows.Forms"
. 还要添加"using System.Windows.Forms;"
到源文件的顶部 - 请参阅下面的完整源代码。关键是要记住"System.Windows.Forms"
在项目级别进行引用。现在将其作为测试代码添加到自定义操作项目的
"CustomAction1"
自定义操作代码片段(请参阅底部的代码部分以获取完整源代码):// will launch the debugger for debug-build dlls #if DEBUG System.Diagnostics.Debugger.Launch(); #endif MessageBox.Show("hello world");
要获得标准设置 GUI(对于阅读此内容的其他人),请按照此处的说明添加对的引用(这是创建可编译并具有 GUI 的基本 WiX 项目的分步操作),然后将其注入您的资源:
WiXUIExtension
<UIRef Id="WixUI_Mondo" />
我喜欢更改
<MediaTemplate />
以<MediaTemplate EmbedCab="yes" />
避免外部源 cab 文件(通过此更改,cab 被编译到 MSI 中)。如果您没有添加任何组件,您可以将其添加到
notepad.exe
您的 MSI 以在目录下进行测试安装INSTALLFOLDER
(只是在没有可用源文件的情况下安装某些东西的技巧 - 应该在任何机器上解析的源路径) - 替换整个“TODO”部分 - 请参阅下面的完整来源:<Component Feature="ProductFeature"> <File Source="$(env.SystemRoot)\notepad.exe" /> </Component>
现在我们需要声明实际的自定义操作并将其插入到安装序列中。让我们在前面添加这个
<Binary> element
:<CustomAction Id="CA1" BinaryKey="CustomActions" DllEntry="CustomAction1"/> <InstallUISequence> <Custom Action="CA1" After="CostFinalize" /> </InstallUISequence> <InstallExecuteSequence> <Custom Action="CA1" After="CostFinalize" /> </InstallExecuteSequence>
现在构建并测试运行 MSI。你应该收到很多
"hello world"
消息。这是
"heartbeat"
C# / 托管代码自定义操作的整体 - 我有时使用它们的方式。
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>
Steps-in-brief:所需更改的简短摘要:
- 将制造商字段设置为某些内容。
- 如上所述添加和修改自定义操作构造。
- 向底部添加组件/文件元素,替换那里的“TODO”部分。
- 将 设置
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;
}
}
}
链接:
推荐阅读
- python - 每次我的计算机从睡眠中醒来时,如何运行 python 脚本?
- javascript - webRequestBlocking - Firefox 中的 URL glob 模式不匹配
- java - 无法在项目上执行目标无法解析项目的依赖关系无法收集依赖关系
- c - Windows 10 上 C/C++ 错误的 IntelliSense 扩展
- linux - ansible playbook中的'cat'命令不会附加文件
- javascript - 用其他数组中的值更新数组中对象的值
- elasticsearch - 我们如何在 Elastic Search 中的文本类型列上聚合 SUM?
- python - 在全局 boto 资源上使用 moto
- r - 从 List 中提取特定元素
- symfony - 参数太多:查询定义了 0 个参数,你绑定了 1 个错误