如何使用 wix 安装程序启用 Windows 功能

问题描述

我使用的是 Windows 10 64 位操作系统。 IT 预先安装了 .net framework 3.5,我们只需要启用它即可让 .net 依赖的应用程序正常工作

我的要求是创建一个新的 MSI,首先启用 .net 3.5,然后安装我的应用程序。

首先我尝试创建 bundle,但 bundle 只创建 EXE,它没有安装 .net 框架的权限。后来我在 Product.wsx 中添加自定义操作来运行“NetFx20SP2_x64.exe”。但我不确定这样做是否正确。

有什么方法可以使用 wix installer(3.11) 启用 .NET framework 3.5,而无需调用可执行文件或创建包。

Bundle.wsx (code snippet)
    <PackageGroup Id="Netfx4Full">
      <ExePackage Id="Netfx4Full" 
                  Cache="yes" 
                  Compressed="yes" 
                  PerMachine="yes" 
                  Permanent="yes" 
                  Vital="yes"
                  InstallCondition="VersionNT64"
                  InstallCommand="/s"
                  UninstallCommand="/s /uninstall"
                  SourceFile=".\NetFx20SP2_x64.exe"
                  DetectCondition="Netfx4FullVersion AND (NOT VersionNT64 OR Netfx4x64FullVersion)"  />
    </PackageGroup>

Custom action in Product.wsx
    <!--CustomAction Id="RegisterEXE"
                  Directory="APPLICATIONROOTDIRECTORY"
                  ExeCommand="&quot;[APPLICATIONROOTDIRECTORY]Upgrade\NetFx20SP2_x64.exe&quot; /Register"
                  Execute="deferred"
                  Return="ignore"  
                  Impersonate="no"
                 /-->

解决方法

你的方式还不错。没有找到没有 CustomAction 的选项来解决这个问题。

我个人更喜欢使用 DISM command 运行 cmd 的自定义操作。在这种情况下,您将有 exit code 显示操作结果。

例如:

var command = @"/c Dism /online /enable-feature /featurename:NetFx3 /All";
var output = string.Empty;
using (var p = new Process())
{
    p.StartInfo = new ProcessStartInfo()
    {
        FileName = "cmd.exe",Arguments = command,UseShellExecute = false,RedirectStandardError = true,RedirectStandardOutput = true,CreateNoWindow = true,};
    p.Start();
    while (!p.StandardOutput.EndOfStream)
    {
        output += $"{p.StandardOutput.ReadLine()}{Environment.NewLine}";
    }
    p.WaitForExit();

    // Here I'll recommend you to analyze the result
    if (p.ExitCode != 0)
    {
    
        throw new Exception($"{p.ExitCode}:{ p.StandardError.ReadToEnd()}");
    }
}