如何为 x86 和 x64 平台指定不同的 BootstrapperPackage-s?

How to specify different BootstrapperPackage-s for x86 and x64 platforms?

在我的 WPF 项目中,我使用了一些第三方平台特定的 dll,例如如果 Platformx86,则该 dll 的 x86 版本被复制到 Output 文件夹中,如果平台是 x64,则 x64 版本是。

这些 dll 还需要 Visual C++ Redistributable。所以我需要它成为 ClickOnce 安装程序运行时安装的先决条件。问题是我只需要 x64 版本的 C++ redist 用于 x64 平台,而 x86 用于 x86 平台。但是我不能只写

<BootstrapperPackage Include="Microsoft.Visual.C++.14.0.x64" Condition="'$(Platform)' == 'x64'">
  <Visible>False</Visible>
  <ProductName>Visual C++ "14" Runtime Libraries %28x64%29</ProductName>
  <Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Visual.C++.14.0.x86" Condition="'$(Platform)' == 'x86'">
  <Visible>False</Visible>
  <ProductName>Visual C++ "14" Runtime Libraries %28x86%29</ProductName>
  <Install>true</Install>
</BootstrapperPackage>

因为 <BootstrapperPackage> 标签不支持 Condition 属性。

也不可能写多个 <ItemGroup> 标签,里面有 <BootstrapperPackage>,因为 Visual Studio 转

<ItemGroup>
  <!--common BootstrapperPackages-->
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x86'">
  <!--BootstrapperPackages for x86-->
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x64'">
  <!--BootstrapperPackages for x64-->
</ItemGroup>

进入

<ItemGroup />
<ItemGroup Condition="'$(Platform)' == 'x86'" />
<ItemGroup Condition="'$(Platform)' == 'x64'">
  <!--All BootstrapperPackages: common, for x86 and for x64-->
</ItemGroup>

我不能包含这两个包,因为在 x86 系统上,x64 C++ 的安装程序会显示错误,而在 x64 系统上,x86 C++ 将被安装但不会被使用。

如何克服这些困难并为不同的平台指定不同的 BootstrapperPackage

即使 csproj 文件中的 BootstrapperPackage 元素支持 Condition 属性,它也只会在编译时应用,这可能不是您想要的。

不幸的是,您将不得不在您的机器上(以及所有部署此代码的机器上)修改 ClickOnce Bootstrapper 程序包清单。

在我的机器上,Microsoft.Visual.C++.14.0.x86Microsoft.Visual.C++.14.0.x64 的清单分别位于 C:\Program Files (x86)\Microsoft SDKs\ClickOnce Bootstrapper\Packages\vcredist_x86\product.xmlC:\Program Files (x86)\Microsoft SDKs\ClickOnce Bootstrapper\Packages\vcredist_x64\product.xml。 (它们也可能在 C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages 或任何其他版本的 Windows SDK 中,具体取决于您的 OS。发布应用程序时的构建日志可能会提到它从哪里复制先决条件。)

在这些文件中,您会找到这样的部分(取自我的 vcredist_x64 清单)

  <!-- These checks determine whether the package is to be installed -->
  <InstallConditions>
    <BypassIf Property="VCRedistInstalled" Compare="ValueGreaterThanOrEqualTo" Value="3"/>
    <!-- Block install if user does not have admin privileges -->
    <FailIf Property="AdminUser" Compare="ValueEqualTo" Value="false" String="AdminRequired"/>
    <!-- Block install on any platform other than x64 -->
    <FailIf Property="ProcessorArchitecture" Compare="ValueNotEqualTo" Value="AMD64" String="InvalidOS"/>
    <!-- Block install on Vista or below -->
    <FailIf Property="VersionNT" Compare="VersionLessThan" Value="6.00" String="InvalidPlatformWinNT"/>
  </InstallConditions>

此行导致错误:

    <FailIf Property="ProcessorArchitecture" Compare="ValueNotEqualTo" Value="AMD64" String="InvalidOS"/>

修改为

    <BypassIf Property="ProcessorArchitecture" Compare="ValueNotEqualTo" Value="AMD64"/>

跳过先决条件而不是失败。 vcredist_x86 配置为安装在 32 位和 64 位 OS 上,如果你想强制它只安装在 32 位系统上,请在其 InstallConditions[= 中添加以下行25=]

    <BypassIf Property="ProcessorArchitecture" Compare="ValueEqualTo" Value="AMD64"/>

相关阅读: