在 .NET 4.0 客户端计算机上将 ClickOnce 证书从 Sha1 迁移到 SHA256 和 运行

Migrate ClickOnce certificate from Sha1 to SHA256 and run on .NET 4.0 client machines

在从 SHA1 升级到 SHA256 签名证书时发现 .NET 4.5 与 .NET 4.0 的签名问题后,我决定重新实施我们的 ClickOnce 构建过程以遵循更标准的方法,以便我可以使用VS2013 更新 3。 不过好像没什么效果。我知道清单正在构建并且工作正常,因为它可以在任何机器上正常安装 运行ning .NET 4.5,但是 .NET 4.0 应用程序仍然失败。

我使用 CruiseControl.NET 来管理我们的构建 要执行 运行 构建,我使用了这两个任务之一,但得到了相同的结果。一个适用于 .NET 4.5 但不适用于 4.0 的 .application 文件,存在文章中提到的错误 例如:

`<devenv>
    <solutionfile>$(SolutionFile)</solutionfile>
    <configuration>$(Config)</configuration>
    <buildtype>Build</buildtype>
    <executable>C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.com</executable>
    <version>VS2013</version>
</devenv>`

或使用 MSBuild:

 <msbuild>
   <executable>C:\Program Files (x86)\MSBuild.0\Bin\MSBuild.exe</executable>
   <workingDirectory>$(WorkingDirectory)</workingDirectory>
   <projectFile>$(SolutionPath)</projectFile>
   <buildArgs>
     /p:Configuration=$(Config) /p:BuildFolder="$(BuildFolder)" 
   </buildArgs>
   <targets>clean;publish</targets>
 </msbuild>

我已经尝试在 msbuild args 中设置工具版本以及许多其他方法,但似乎没有任何效果并迫使我的最终用户卸载并重新安装我试图避免的情况。

在过去的两周里,我一直在与 ClickOnce 作斗争,以尝试防止迁移到新证书时出现任何问题,但我似乎无法使最后这一步正常工作。非常感谢此处的任何指导。

此问题的解决方案不明确且记录不完整,但在对代码和 msbuild 文件进行大量修改后,我找到了解决方案。

对于我 运行 遇到的具体问题,此答案可能不完整,但我会尽力为 运行 遇到此问题的任何其他人提供基础。

首先,对于构建目标,我们需要做一个小改动,我们需要将 MSBuild 的工具版本设置为最新最好的,这样我们就可以利用错误修复来解决 ClickOnce 无法使用的特定问题在仅安装 .NET 4.0 的计算机上 运行 时的 SHA256 证书。我们通过在构建机器上安装 Visual Studio 2013 或更高版本来实现这一点,因此我们可以使用最新版本的 MSbuild。 注意这里的可执行文件路径里面有"MSBuild.0"。我们至少需要版本 12 才能正常工作。

<msbuild>
  <executable>C:\Program Files (x86)\MSBuild.0\Bin\MSBuild.exe</executable>
  <workingDirectory>$(WorkingDirectory)</workingDirectory>
  <projectFile>$(SolutionPath)</projectFile>
  <buildArgs>
    /tv:12.0 /p:Configuration=$(Config) /p:BuildFolder="$(BuildFolder)" 
  </buildArgs>
  <targets>clean;publish</targets>
</msbuild> 

进行此更改后,我 运行 遇到了由存在的遗留构建配置引起的许多其他问题。为了使用此 MSBuild,我必须将 ClickOnce 构建恢复为您在任何 ClickOnce 示例中看到的基本格式。这对未来有好处,但也带来了很多问题。

一个难以解决的具体问题是 AssemblyIdentity 现在设置为 AssemblyName.application,而我有一个自定义值, MyCustomIdentity.app

我花了一些时间来验证身份实际上是从 Projects AssemblyName 值派生的。

我通过检查 Microsoft.Common.targets 文件发现了这一点,查看默认构建目标我发现有一个标签

<_DeploymentDeployManifestIdentity>$(AssemblyName)</_DeploymentDeployManifestIdentity>

因为这仍然只是 MSBuild XML,我意识到我可以将其复制出来并将其推送到我的项目文件中以设置我自己的项目文件,但是您在文件中的哪个位置执行此操作很重要。

您必须将它放在目标导入之后,这可能会覆盖它。我通过将它添加为项目下的最后一个元素来确保安全。

<_DeploymentDeployManifestIdentity> MyCustomIdentity.app </_DeploymentDeployManifestIdentity>