Reputation: 1593
I am using the following to sign my output dll.
The problem is that this makes signing to run every time the build is done which kills incremental build.
I tried using Inputs="$(TargetPath)" Outputs="$(TargetPath)"
, but this doesn't run sign task at all.
A possible solution is to compile into different folder and then copy with signing which makes this more cumbersome.
Is there something simpler?
<Target Name="Sign" AfterTargets="Build">
<Exec Command="signtool sign /f "$(SolutionDir)my.pfx" /p password /t http://timestamp.verisign.com/scripts/timstamp.dll "$(TargetPath)"" />
</Target>
Upvotes: 0
Views: 3072
Reputation: 1593
The answer is simply to not sign when linkage was not involved.
<!-- Sign only if produced an output-->
<Target Name="SignOutput" AfterTargets="CoreBuild;Link" BeforeTargets="PostBuildEvent;AfterBuild" Condition="'$(LinkSkippedExecution)' == 'False'">
<Message Importance="High" Text="Signing $(TargetPath)"/>
<Exec Command="signtool ... " /> <!-- Either manugally calling signtool -->
<SignFile .../> <!-- Or any other command to sign -->
</Target>
Upvotes: 0
Reputation: 788
This snippet of MSBuild configuration will sign the output assemblies using signtool, and timestamp them for Release configurations, assuming the version of .NET Framework is new enough to use Roslyn.
Roslyn triggers the "SignExe" target whenever it compiles.
<PropertyGroup>
<TargetsTriggeredByCompilation>
SignExe
</TargetsTriggeredByCompilation>
</PropertyGroup>
<Target Name="SignExe">
<PropertyGroup>
<CodeSignThumbprint>SHA1CERTTHUMBPRINTHERE</CodeSignThumbprint>
</PropertyGroup>
<SignFile SigningTarget="@(IntermediateAssembly)" CertificateThumbprint="$(CodeSignThumbprint)" TargetFrameworkVersion="$(TargetFrameworkVersion)" TimestampUrl="http://timestamp.verisign.com/scripts/timstamp.dll" Condition="'$(Configuration)' == 'Release'"></SignFile>
<SignFile SigningTarget="@(IntermediateAssembly)" CertificateThumbprint="$(CodeSignThumbprint)" TargetFrameworkVersion="$(TargetFrameworkVersion)" Condition="'$(Configuration)' != 'Release'"></SignFile>
</Target>
Upvotes: 1
Reputation: 76760
Sign file MSBuild with incremental build
Just as you know, we do not need to sign the output dll every time, so usually we always use the command line with command prompt to complete it when we need to sign it:
This tool is automatically installed with Visual Studio. To run the tool, use the Developer Command Prompt (or the Visual Studio Command Prompt in Windows 7). For more information, see Command Prompts.
Or we could use custom target to execute it, but without AfterTargets="Build
, otherwise, it will always be executed when we build the project, just like what you said "which kills incremental build.".
When we need to sign output dll, we use the MSBuild.exe to build the project with specify the target Sign
, like:
MSBuild.exe /t:build,test "Yoursolution.sln"
Hope this helps.
Upvotes: 0