在签署EXE时,“文件具有与清单中指定的计算哈希值不同”错误

时间:2012-09-20 22:09:55

标签: c# msbuild clickonce msbuild-task

我的ClickOnce安装失败并显示错误:

  

文件,WindowsFormsProject.exe,具有与清单中指定的不同的计算哈希值。

我使用MSBuild生成ClickOnce部署包。构建脚本中的相关行:

<MSBuild Targets="Publish"
         Projects="WindowsFormsProject.csproj"
         ContinueOnError="false" />

WindowsFormsProject.csproj有一个Post-Build步骤,用于签署可执行文件,如下所示:

signtool sign /a $(ProjectDir)\obj\$(PlatformName)\$(ConfigurationName)\$(TargetFileName)

问题是,当我查看构建日志时,我发现在Post-Build事件执行之前就生成了清单。因此哈希码不匹配就不足为奇了。构建日志中的相关行:

  

_CopyManifestFiles:

     

WindowsFormsProject - &gt; ... \ WindowsFormsProject.application

     

...

     

PostBuildEvent:

     

成功签名:... \ WindowsFormsProject.exe

所以,问题是:

  1. 在&lt; MSBuild&gt;期间生成清单之前,有没有办法对程序集进行签名?任务?
  2. 有没有办法在构建完成后重新生成清单(并且只显示清单),以便哈希码再次匹配?
  3. 或者,如果你能想出一个不同的问题解决方案,我会很感激你的想法。

3 个答案:

答案 0 :(得分:8)

如果您使用的是MSBuild 4,则可以使用 AfterTargets 属性在刚刚创建程序集之后以及在执行任何进一步的步骤之前对程序集进行签名。删除您的构建后步骤,并将此块添加到您的项目中:

<Target Name="SignOutput" AfterTargets ="CoreCompile">
  <PropertyGroup>
    <TimestampServerUrl>http://timestamp.verisign.com/scripts/timstamp.dll</TimestampServerUrl>
  <ApplicationDescription>Foo bar</ApplicationDescription>
  <SigningCertificateCriteria>/sha1 578a9486f10ed1118f2b5f428afb842e3f374793</SigningCertificateCriteria>
  </PropertyGroup>
  <ItemGroup>
    <SignableFiles Include="$(ProjectDir)obj\$(PlatformName)\$(ConfigurationName)\$(TargetName)$(TargetExt)" />
  </ItemGroup>
  <GetFrameworkSdkPath>
          <Output
              TaskParameter="Path"
              PropertyName="SdkPath" />
  </GetFrameworkSdkPath>
    <Exec Command="&quot;$(SdkPath)bin\signtool&quot; sign $(SigningCertificateCriteria) /d &quot;$(ApplicationDescription)&quot; /t &quot;$(TimestampServerUrl)&quot; &quot;%(SignableFiles.Identity)&quot;" />
</Target>

答案 1 :(得分:3)

归功于Dmitriy的回答。但是我不得不对德米特里的答案做一些改变,让它适合我。具体做法是:

  • 我为&#34; Target&#34;
  • 添加了结束标记
  • 我使用的是Windows 8.1,并且必须更改signtool.exe路径
  • 我正在使用PFX文件并且必须指定密码
  • 我不需要添加他提供的所有信息

请修改&#34; my_signing_file.pfx&#34;,&#34; mypassword&#34;,&#34; myexe.exe&#34;并使这项工作适合你:

<Target Name="SignOutput" AfterTargets="CoreCompile">
<Exec Command="&quot;C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe&quot; sign /f &quot;$(ProjectDir)my_signing_file.pfx&quot; /p mypassword &quot;$(ProjectDir)obj\$(ConfigurationName)\myexe.exe&quot;" />
</Target>

答案 2 :(得分:1)

您可以从VisualStudio配置程序集的签名过程和ClickOnce清单:

  1. 右键单击您的项目&gt;属性&gt;签名。
  2. 选中“签署ClickOnce Manifest”并选择您要使用的证书。
  3. 选中“签署程序集”并选择要使用的证书。
  4. 保存所有更改并重新发布。
  5. 使用MsBuild构建时,所有这些设置都有效。

    注意:如果需要,您可以从该屏幕生成自签名证书。

    注2:请记住,您有两个清单“Application Manifest”和“Deployment Manifest”都必须使用相同的证书进行签名。

    如果您需要在构建后随时重新签署清单,可以使用Mage.exe