Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stripping annotations also strips the signature away from strong-named assemblies #2

Closed
tankbob opened this issue Jun 15, 2020 · 5 comments
Assignees
Labels
bug [issue/PR] reports / solves a bug.

Comments

@tankbob
Copy link

tankbob commented Jun 15, 2020

This task does not work if the assembly is strong named as it breaks the signature.

Need some way of either stripping the assembly before strong naming occurs or reapplying the strong name afterwards.

@rdeago rdeago added bug [issue/PR] reports / solves a bug. help wanted labels Aug 11, 2020
@rdeago rdeago changed the title Strong Named Assemblies Stripping annotations also strips the signature away from strong-named assemblies Aug 11, 2020
@rdeago rdeago self-assigned this Aug 11, 2020
@rdeago
Copy link
Member

rdeago commented Aug 11, 2020

@tankbob sorry for not replying sooner.

You're right, this needs to be solved. Any idea about it is welcome.

I confess I'm learning about strong-named assemblies in these last weeks - I had been avoiding the topic entirely for years, shame on me.

These days I'm trying to speed up the release of Buildvana SDK, which, among other things, will automate assembly signing with separate keys for local and CI builds. This issue is clearly a show-stopper for it too. The good news is I'm soon going to be on it. Again, any help or suggestion is greatly appreciated!

@tankbob
Copy link
Author

tankbob commented Aug 17, 2020

I'm using the following Extra Targets

<PropertyGroup>
    <SNPath Condition="'$(SNPath)'==''"></SNPath>
    <SignAssembly Condition="'$(SignAssembly)'==''"></SignAssembly>
    <AssemblyOriginatorKeyFile Condition="'$(AssemblyOriginatorKeyFile)'==''"></AssemblyOriginatorKeyFile>
  </PropertyGroup>

<Target Name="GetSNPath" BeforeTargets="FixStrongName">
  <GetFrameworkSdkPath>
    <Output TaskParameter="Path" PropertyName="WindowsSdkPath" />
  </GetFrameworkSdkPath>
  <Exec Command="WHERE /r &quot;$(WindowsSdkPath.TrimEnd('\\'))&quot; sn &gt; sn-path.txt"  />
  <ReadLinesFromFile File="sn-path.txt">
    <Output TaskParameter="Lines" PropertyName="SNPath"/>
  </ReadLinesFromFile>
  <Delete Files="sn-path.txt" />
  <PropertyGroup>
    <SNPath>$([System.Text.RegularExpressions.Regex]::Replace('$(SNPath)', ';.*', ''))</SNPath>
  </PropertyGroup>
</Target>
  
<Target Name="FixStrongName" AfterTargets="_TenacomExportAnnotations_CopyFilesToOutputDirectory" Condition="$(SignAssembly) == 'True'">
  <Message Text="Resigning after Export Annotations for $(ProjectName)" Importance="High" />
  <Exec Command="&quot;$(SNPath)&quot; -R &quot;$(TargetPath)&quot; &quot;$(MSBuildProjectDirectory)\$(AssemblyOriginatorKeyFile)&quot;" />
</Target>

@rdeago
Copy link
Member

rdeago commented Aug 17, 2020

@tankbob thanks a lot for sharing! That's not going to cut it for non-Windows builds, however.

In the meantime I've found StrongNameSigner, a .NET library that seems to be able to sign assemblies in C# using Cecil. I cannot reference it from ReSharper.ExportAnnotations.Core because it's compiled for .NET Framework 4.0, but I may be able to lift some code from it(*) to re-sign assemblies as soon as I modify them, probably taking the value of <AssemblyOriginatorKeyFile> as a parameter. This could work on all systems, as long as the relevant BCL methods are supported, which I haven't yet checked.


(*) Of course I plan to include a third-party copyright notice. StrongNameSigner's Apache 2.0 license shouldn't be a problem: MSBuild is another MIT-licensed project containing Apache-licensed material.

@rdeago
Copy link
Member

rdeago commented Aug 17, 2020

On an unrelated note, you don't need an Exec to find sn.exe:

<PropertyGroup>
    <SNPath Condition="'$(SNPath)'==''"></SNPath>
    <SignAssembly Condition="'$(SignAssembly)'==''"></SignAssembly>
    <AssemblyOriginatorKeyFile Condition="'$(AssemblyOriginatorKeyFile)'==''"></AssemblyOriginatorKeyFile>
  </PropertyGroup>

<Target Name="GetSNPath" BeforeTargets="FixStrongName">
  <GetFrameworkSdkPath>
    <Output TaskParameter="Path" PropertyName="WindowsSdkPath" />
  </GetFrameworkSdkPath>
  <!-- Make sure there's a trailing path separator. -->
  <PropertyGroup>
    <WindowsSdkPath>$([MSBuild]::EnsureTrailingSlash('$(WindowsSdkPath)'))</WindowsSdkPath>
  </PropertyGroup>
  <!-- Find all files called sn.exe under the SDK path. -->
  <ItemGroup>
    <SNExe Include="$(WindowsSdkPath)**\sn.exe" />
  </ItemGroup>
  <PropertyGroup>
    <!-- Turn items into a semicolon-separated list. -->
    <SNPath>@(SNExe)</SNPath>
    <!-- If there's more than one sn.exe, keep the first and discard the others. -->
    <SNPath Condition="@(SNExe->Count()) > 1">$(SNPath.Remove($(SNPath.IndexOf(';'))))</SNPath>
  </PropertyGroup>
</Target>

<Target Name="FixStrongName" AfterTargets="_TenacomExportAnnotations_CopyFilesToOutputDirectory" Condition="$(SignAssembly) == 'True'">
  <Message Text="Resigning after Export Annotations for $(ProjectName)" Importance="High" />
  <Exec Command="&quot;$(SNPath)&quot; -R &quot;$(TargetPath)&quot; &quot;$(MSBuildProjectDirectory)\$(AssemblyOriginatorKeyFile)&quot;" />
</Target>

@rdeago
Copy link
Member

rdeago commented Oct 3, 2020

@tankbob since I don't modify assemblies using Cecil any more, I closed this issue.

Please use the latest version of ReSharper.Annotations.Task, signatures should be preserved now.

If you're still having the same problem, please comment below and I'll reopen the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug [issue/PR] reports / solves a bug.
Projects
None yet
Development

No branches or pull requests

2 participants