My ClickOnce installation fails with an error:
File, WindowsFormsProject.exe, has a different computed hash than specified in manifest.
I use MSBuild to generate ClickOnce deployment package. The relevant line from the build script:
<MSBuild Targets="Publish"
Projects="WindowsFormsProject.csproj"
ContinueOnError="false" />
The WindowsFormsProject.csproj has a Post-Build step that signs the executable, as follows:
signtool sign /a $(ProjectDir)\obj\$(PlatformName)\$(ConfigurationName)\$(TargetFileName)
The trouble is, when I look at the build log I see that the manifest is generated BEFORE the Post-Build event executes. So it's not surprising that hash codes don't match. The relevant lines from the build log:
_CopyManifestFiles:
WindowsFormsProject -> ...\WindowsFormsProject.application
...
PostBuildEvent:
Successfully signed: ...\WindowsFormsProject.exe
So, the questions are:
Or, if you can think of a different solution to the problem, I'd appreciate your ideas.
If you are using MSBuild 4, you can use AfterTargets property to sign assembly just after it was created and before any further steps will be taken. Remove your post-build step and add this block to your project instead:
<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=""$(SdkPath)bin\signtool" sign $(SigningCertificateCriteria) /d "$(ApplicationDescription)" /t "$(TimestampServerUrl)" "%(SignableFiles.Identity)"" />
</Target>
The credit goes to Dmitriy for his answer. However I had to make slight changes to Dmitry's answer to make it work for me. Specifically:
Please modify the values for "my_signing_file.pfx", "mypassword", "myexe.exe" and to make this work for you:
<Target Name="SignOutput" AfterTargets="CoreCompile">
<Exec Command=""C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe" sign /f "$(ProjectDir)my_signing_file.pfx" /p mypassword "$(ProjectDir)obj\$(ConfigurationName)\myexe.exe"" />
</Target>
You can configure the signing process of the assembly and the ClickOnce manifest from VisualStudio:
All these settings will be valid when you build using MsBuild.
Note: You can generate your self-signed certificate from that screen if required.
Note 2: Remember that you have TWO manifests "Application Manifest" and "Deployment Manifest" both must be signed with the same certificate.
If you need to re-sign your manifests at any time after the build you can use Mage.exe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With