0

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 &quot;$(SolutionDir)my.pfx&quot; /p password /t http://timestamp.verisign.com/scripts/timstamp.dll &quot;$(TargetPath)&quot;" />
</Target>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
NN_
  • 1,593
  • 1
  • 10
  • 26

3 Answers3

1

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>
Chloride Cull
  • 741
  • 1
  • 7
  • 16
0

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:

SignTool.exe (Sign Tool):

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.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • I do need to sign dll for each build. I have code that validates dll signature. – NN_ Sep 28 '18 at 13:33
  • Not sure why. Add logging to the build and check with MSBuild log viewer https://msbuildlog.com/ – NN_ Feb 02 '22 at 07:22
0

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>
NN_
  • 1,593
  • 1
  • 10
  • 26
  • Hi - i am using this, but am occasionally getting errors where either the signing fails, because the file is "in use", any idea if that could be my fault, or if it has something to do with this target? – Whosdatdev Jan 31 '22 at 13:06