在我的刻录引导程序中打包 .Net 可再发行组件

Package the .Net redistributable in my burn bootstrapper

我正尝试按照 page.

上的说明将 .Net 4.5.2 可再发行组件打包到我的刻录应用程序中

但是在临时刻录位置找不到文件。

根据日志 burn 尝试在此处找到文件:

[0A14:09C4][2015-05-12T16:48:52]w343: Prompt for source of package: NetFx452Redist, payload: NetFx452Redist, path: `C:\Users\simon\Desktop\redist\NDP452-KB2901907-x86-x64-AllOS-ENU.exe`

但文件实际上最终位于一个临时文件夹中

例如

C:\Users\simon\AppData\Local\Temp\{f5207472-d2a0-4b00-b9ee-c535385bde58}\redist\NDP452-KB2901907-x86-x64-AllOS-ENU.exe

说明说要这样做:

<PayloadGroup Id="NetFx452RedistPayload">
  <Payload Name="redist\NDP452-KB2901907-x86-x64-AllOS-ENU.exe"
           SourceFile="..\..\Binaries\Microsoft\NetFramework.5.2\NDP452-KB2901907-x86-x64-AllOS-ENU.exe"/>
</PayloadGroup>

如何让 Burn 在正确的位置查找 .net 安装程序?

而不是引用 NetFxExtension,您可以通过直接引用 .NET 安装包来获得更多控制权:

<Fragment>
  <!-- Value of the 'Release' registry value when .NET 4.5.2 is installed -->
  <?define NetFx452MinRelease = 379893 ?>

  <!-- Get the release of the .NET V4 framework currently installed -->
  <util:RegistrySearch
        Id="NETFRAMEWORK4"
        Variable="NETFRAMEWORK4"
        Root="HKLM"
        Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
        Value="Release"
        Result="value" />

  <!-- Install .NET 4.5.2 if not already installed -->
  <PackageGroup Id="NetFx4FullRedist">
    <ExePackage
        Id="NetFx4FullRedist"
        Cache="no"
        Compressed="yes"
        InstallCommand="/q /norestart /ChainingPackage &quot;[WixBundleName]&quot;"
        RepairCommand="/q /norestart /repair /ChainingPackage &quot;[WixBundleName]&quot;"
        UninstallCommand="/uninstall /q /norestart /ChainingPackage &quot;[WixBundleName]&quot;"
        PerMachine="yes"
        DetectCondition="NETFRAMEWORK4 &gt;= $(var.NetFx452MinRelease)"
        Vital="yes"
        Permanent="yes"
        Protocol="netfx4"
        SourceFile="..\..\Binaries\Microsoft\NDP452-KB2901907-x86-x64-AllOS-ENU.exe"
        Name="Redist\NDP452-KB2901907-x86-x64-AllOS-ENU.exe">
    </ExePackage>
  </PackageGroup>
</Fragment>

然后在您的 <chain>..</chain> 中引用 NetFx4FullRedist:

  <!-- .NET runtime full profile -->
  <PackageGroupRef Id="NetFx4FullRedist"/>

我使用了一个变体来将 .NET 4 Client 重新分发到我的刻录生成的安装程序应用程序中,没有任何问题。

为 DotNet 框架添加一个 ExePackage 元素会起作用,但也可以使用 PayloadGroup:

<PayloadGroup Id="NetFx452RedistPayload">
    <Payload Name="redist\NDP452-KB2901907-x86-x64-AllOS-ENU.exe"
             SourceFile="X:\path\to\redists\in\repo\NDP452-KB2901907-x86-x64-AllOS-ENU.exe"/>
<PayloadGroup/>

引用该组以便将其包含在您的负载中:

<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost">
  <PayloadGroupRef Id="NetFx452RedistPayload"/>

您还需要在链中添加对 NetFx452Redist 的引用:

<Chain>
  <PackageGroupRef Id="NetFx452Redist" />

在应用阶段,源将无法解析(除非您在与您的包相关的名为 "redist" 的文件夹中有 NDP452-KB2901907-x86-x64-AllOS-ENU.exe)。要指向负载中包含的 NDP452-KB2901907-x86-x64-AllOS-ENU.exe,诀窍是为 ResolveSource 事件添加一个事件处理程序。

ResolveSource += ResolveSourceHandler;

  private void ResolveSourceHandler(object sender, ResolveSourceEventArgs args)
  {
     try
     {
        //Everything from the "CurrentBundle" class is from my model.
        //The model is built from parsing BootstrapperApplicationData.xml.
        //Specifically, payload comes from WixPayloadProperties.
        var payload = CurrentBundle.PayloadList.FirstOrDefault(x => string.Compare(x.Id, args.PayloadId, StringComparison.OrdinalIgnoreCase) == 0);
        var newPayloadPath = (payload != null) ? Path.Combine(CurrentBundle.WorkingFolder, payload.Name) : string.Empty;

        if (File.Exists(newPayloadPath))
        {
           Engine.SetLocalSource(args.PackageOrContainerId, args.PayloadId, newPayloadPath);
           args.Result = Result.Retry;
        }
        else if (File.Exists(args.LocalSource) == false && string.IsNullOrEmpty(args.DownloadSource) == false)
        {
           args.Result = Result.Download;
        }
     }
     catch (Exception ex)
     {
        args.Result = Result.Error;
     }
  }