You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用WiX安装含System.Configuration.Install.Installer的.NET程序集

刚好之前帮同事处理过几乎一模一样的场景——依赖第三方SDK的插件,自带System.Configuration.Install.Installer实现,又不能改SDK代码,还得避开WiX不推荐的InstallUtil.exe。给你两个最靠谱的方案,都是社区和WiX官方认可的:

方案一:用DTF托管自定义操作直接调用Installer逻辑

这是最推荐的方式,既不用调用外部工具,又能100%复用SDK的安装逻辑,完全符合WiX的最佳实践。

步骤1:创建DTF自定义操作项目

在你的解决方案里添加一个WiX Toolset Managed Custom Action Project(这是WiX自带的DTF项目模板,专门用来写托管自定义操作)。

步骤2:编写自定义操作代码

直接在代码里加载插件程序集,找到SDK定义的安装类子类,调用它的Install/Uninstall方法。示例代码如下:

using System;
using System.Collections;
using System.Configuration.Install;
using System.Linq;
using System.Reflection;
using Microsoft.Deployment.WindowsInstaller;

public class PluginInstallActions
{
    [CustomAction]
    public static ActionResult InstallPlugin(Session session)
    {
        try
        {
            // 从WiX属性获取插件安装路径(提前在WiX里定义好INSTALLFOLDER属性)
            string pluginPath = $"{session["INSTALLFOLDER"]}YourPluginAssembly.dll";
            session.Log($"Loading plugin assembly from: {pluginPath}");

            // 加载插件程序集
            Assembly pluginAssembly = Assembly.LoadFrom(pluginPath);
            
            // 找到继承自SDK安装类的Installer实现(替换成你的SDK基类名)
            var installerType = pluginAssembly.GetTypes()
                .First(t => typeof(YourSDKBaseInstaller).IsAssignableFrom(t) && !t.IsAbstract);
            
            // 实例化并执行安装
            using (Installer installer = (Installer)Activator.CreateInstance(installerType))
            {
                installer.Context = new InstallContext(null, new string[] { });
                installer.Install(new Hashtable());
                session.Log("Plugin installation completed successfully");
            }

            return ActionResult.Success;
        }
        catch (Exception ex)
        {
            session.Log($"Error installing plugin: {ex.Message}\n{ex.StackTrace}");
            return ActionResult.Failure;
        }
    }

    [CustomAction]
    public static ActionResult UninstallPlugin(Session session)
    {
        try
        {
            string pluginPath = $"{session["INSTALLFOLDER"]}YourPluginAssembly.dll";
            session.Log($"Loading plugin assembly for uninstall: {pluginPath}");

            Assembly pluginAssembly = Assembly.LoadFrom(pluginPath);
            var installerType = pluginAssembly.GetTypes()
                .First(t => typeof(YourSDKBaseInstaller).IsAssignableFrom(t) && !t.IsAbstract);
            
            using (Installer installer = (Installer)Activator.CreateInstance(installerType))
            {
                installer.Context = new InstallContext(null, new string[] { });
                installer.Uninstall(null);
                session.Log("Plugin uninstallation completed successfully");
            }

            return ActionResult.Success;
        }
        catch (Exception ex)
        {
            session.Log($"Error uninstalling plugin: {ex.Message}\n{ex.StackTrace}");
            return ActionResult.Failure;
        }
    }
}

步骤3:在WiX项目里引用并配置自定义操作

编译自定义操作项目后,把生成的.CA.dll文件添加到WiX项目中,然后在WiX源文件里配置:

<!-- 引用自定义操作DLL -->
<Binary Id="PluginInstallCA" SourceFile="$(var.PluginInstallActions.TargetDir)PluginInstallActions.CA.dll" />

<!-- 定义安装自定义操作:必须用deferred模式,因为要等文件安装完成后才能加载插件 -->
<CustomAction Id="ExecutePluginInstall" BinaryKey="PluginInstallCA" DllEntry="InstallPlugin" 
              Execute="deferred" Impersonate="no" Return="check" />

<!-- 定义卸载自定义操作 -->
<CustomAction Id="ExecutePluginUninstall" BinaryKey="PluginInstallCA" DllEntry="UninstallPlugin" 
              Execute="deferred" Impersonate="no" Return="check" />

<!-- 把自定义操作加入安装序列 -->
<InstallExecuteSequence>
  <!-- 安装:在文件安装完成后执行 -->
  <Custom Action="ExecutePluginInstall" After="InstallFiles">NOT Installed</Custom>
  <!-- 卸载:在文件删除前执行 -->
  <Custom Action="ExecutePluginUninstall" Before="RemoveFiles">REMOVE="ALL"</Custom>
</InstallExecuteSequence>
关键注意事项
  • 执行模式:必须用Execute="deferred",因为只有文件安装到目标目录后,才能加载插件程序集;同时deferred模式下自定义操作会以管理员权限运行(如果MSI是elevated启动的),避免权限不足。
  • 权限设置:Impersonate="no"确保自定义操作以系统权限执行,符合安装程序的权限要求。
  • 日志记录:一定要用session.Log()记录关键步骤和错误信息,WiX安装日志里会显示这些内容,方便排查问题。
  • 异常处理:必须捕获所有异常并返回ActionResult.Failure,否则MSI会静默失败,难以定位问题。

内容的提问来源于stack exchange,提问作者Hydrargyrum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:33:06