Wix:自定义操作能走多远?
Posted
技术标签:
【中文标题】Wix:自定义操作能走多远?【英文标题】:Wix: How far can I go with custom action? 【发布时间】:2013-07-31 19:39:35 【问题描述】:我想构建一个 Wix 安装程序,它将检测我的一些程序并更新它们。
我有 c# 代码(使用另一个 DLL)来检查系统上的一些东西, 然后我想下载所有应用程序的最新版本的表格, 决定我需要更新哪个应用程序,然后下载并更新选定的应用程序。
所以我的问题是,Wix 可以执行以下操作吗:
1) 使用 c# 运行另一个 dll 调用?
2) 从网上下载一个文件并解析它(比方说 - 也使用 c#)?
3) 转到链接并下载 MSI\EXE?
4) 安装 MSI\EXE(假设在静默模式下运行)?
5)从系统中卸载旧的其他应用程序?
【问题讨论】:
我想你可以随心所欲。这是否是好的设计是另一个问题...... 【参考方案1】:Windows Installer 有一个互斥锁,它只允许每台机器 1 个执行序列和每个进程 1 个 UI 序列。由于此限制,一个 MSI 无法安装另一个 MSI。这方面有一些技巧,但它们没有遵循良好的设计(不提供适当的提升支持或静默安装/卸载支持)。
您应该谨慎使用自定义操作。正确设计的自定义操作的行为应类似于 Windows Installer 中内置的标准操作。即尽可能支持事务安装,并通过自定义表进行数据驱动。
对于您所描述的需要完成的事情,一个更好的候选者可能是引导程序/链接器,例如 WiX 的刻录功能。
【讨论】:
【参考方案2】:1) - 肯定是的
2)-5) 你可以这样做,但你应该将 msi 与“自定义引导程序”和“安装配置管理器后自定义”区分开来。一般规则:仅将 msi 包用于资源(通常是文件;在更复杂的情况下 - 注册表,大多数情况下是 sql 对象)原子部署;将所有其他功能移到 msi 之外(意味着使用 wix only 构建 msi;为引导程序和配置工具创建自定义实用程序;查看 wix 示例如何将三个部分集成在一起)。
【讨论】:
谢谢!您能解释一下 msi 和引导程序/“配置管理器”之间的区别吗?他们仍然是 Wix 的一部分,但不是 MSI? MSI SDK 带有一个非常简单的示例 setup.exe 项目,但除此之外什么都没有。他们把这个问题留给了工具提供商(当时主要是 InstallShield)。 *.msi 是 Winodows Installer 工具的指令包。你可以使用 wix 创建这样的包。 Bootsraper 是通常管理/安装先决条件并在此之后启动 Windows 安装程序过程的自定义应用程序。任何 setup.exe 都是引导程序。 Wix 带来了它的一个示例,最后一个版本提出了“通用引导程序”,但它并不灵活。自定义配置管理器是一个自定义应用程序,可以在 msi 成功安装所有文件后使用,例如配置用户访问。 Wix 主要用于创建 msi 包。【参考方案3】:1) 是的,但请记住,如果您依赖 .NET 3.5 并且您使用的是 .NET 4 的机器,您的自定义操作将无法运行。 除此之外,您的自定义操作 dll 从 msi 解压缩到 %TEMP% 文件夹中。如果您对未存储在 GAC 中的其他 dll 有任何依赖关系,您将无法加载。如果你带来另一个,例如C++ dll 您必须将其作为资源嵌入到您的 C# dll 中并解压缩以找到它。
2) 你可以做任何你有权做的事情。
3) 当然
4) 一次只能运行一个 MSI 安装。您必须生成一些子进程才能等到当前安装结束。
5) 是的,当然。最简单的方法是将升级表添加到您的 msi,以简单地卸载具有此升级代码的任何软件。这是唯一允许同时激活两个 msis 的操作。查看 RemoveExistingProducts 操作的 InstallExecute Sequence 表。
【讨论】:
重新 .NET 3.5/40。这不是真的。您可以为 .NET 2.0/3.0/3.5 编译程序集并告诉它 4.0 是受支持的运行时。你所说的GAC 也不是真的。您可以将文件作为引用或内容添加到您的 DTF 自定义操作项目中,它们都会被解压缩到 temp 目录中。 对于 Wix 可能是这样,但如果您直接部署例如具有非托管入口点的托管 C++ 程序集。纯 MSI 逻辑对 .NET 一无所知。它确实会提取您的 dll 并执行指定的入口点,然后在执行您的自定义操作后卸载 dll。 您可能想阅读有关 WiX DTF 的信息。它在五年前解决了所有这些问题。 blog.iswix.com/2008/05/…以上是关于Wix:自定义操作能走多远?的主要内容,如果未能解决你的问题,请参考以下文章
WiX 自定义操作项目 - BadImageFormatException