Is there an easy way to sign a C++ CLI assembly in

2019-02-04 09:47发布

问题:

Right now I am setting the Linker/Advanced/KeyFile option.

I am getting the "mt.exe : general warning 810100b3: is a strong-name signed assembly and embedding a manifest invalidates the signature. You will need to re-sign this file to make it a valid assembly.".

Reading from the web, it sounds like I have to set the delay signing option, download the SDK, and run sn.exe as a post build event. Surely there must be an easier way to do this common operation in VS2010?

回答1:

There's a fair amount of lameness here, this just never worked before. It got "fixed" in VS2010, mt.exe now generates a warning instead of letting this silently go wrong. Not a real fix, and there's not an obvious one, the linker can't just embed the signature and still allow mt.exe to run afterwards.

The solution is to re-sign the assembly with a post-build event. Make it look like this:

Command = sn -Ra "$(TargetPath)" $(ProjectName).snk

If you don't already have the key file, you'll need to create the .snk file yourself, run sn.exe from the Visual Studio Command prompt. for example:

cd \whereTheProjectIsLocated
sn.exe -k MyProject.snk

Or extract it from a container or use your designated key file. Delay signing is just a matter of running sn.exe with the proper command line options.



回答2:

If you can't/won't edit Microsoft.Cpp.Win32.targets, adding the following to the project file also works:

<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- snip -->
    <ItemDefinitionGroup>
      <Link>
        <KeyFile>$(LinkKeyFile)</KeyFile>
      </Link>
    </ItemDefinitionGroup>
</Project>


回答3:

Paul Mead's proposal is on the right track, but this seems definitive: http://blogs.msdn.com/b/vcblog/archive/2011/03/11/10140139.aspx. Note that it's easy to change the text but omit to change the "%" to a "$".



回答4:

I ran into this problem with VS2010 SP1 for the WIN32 platform. Looking at the build .log file I found that the /KEYFILE parameter was given to the initial link for the .DLL, but after the manifest was created and the second link was done to include the manifest the /KEYFILE parameter was missing. After looking around a bit I found that the problem is in the file Microsoft.Cpp.Win32.targets in C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32. There is a typo for the KeyFile attribute for the second link. I fixed it by changing line 441:

    KeyFile                        ="%(Link.KeyFile)"

to

    KeyFile                        ="$(LinkKeyFile)"

With that change the second linker pass included the /KeyFile qualifier and the .DLL was properly built with the publickey embedded.



回答5:

In my experience, the simplest way is to:

1) Open the Visual Studio Command Prompt 2010 . Go to your project directory (it's the directory that contains your source files). Then type sn -k yourKeyName.snk .

2) Open your project in visual studio 2010 and open up the AssemblyInfo.cpp file and add this line [assembly:AssemblyKeyFileAttribute("yourKeyName.snk")]; .

3) Open up Project->Properties->Linker->Advanced. And in the "Key File" slot and put yourKeyName.snk. Also in the "Delay Sign" slot select Yes (\DELAYSIGN) .

4) Build your project as normal.



回答6:

Phil Atkin's reply and link is the way to fix this bug. Microsoft finally got around to addressing it for Visual Studio 2010 but they never released a service pack fix. Go to this link for the MS explanation and multiple ways to fix it.

http://blogs.msdn.com/b/vcblog/archive/2011/03/11/10140139.aspx

It worked for me. Thanks Phil. (I'd up vote you, but I'm still a newbie.)

Edit for Mzedeler:
Here is the most relevant info from the link that most people will be able to use. It's skips the history and multi-project implications. (Go to the link to see that stuff.)

First: Fix the typo in the build process:

  1. In Windows 7: Go to Start->All Programs->Accessories
  2. Right click on Command Prompt icon and select "Run as Administrator" from the drop list.
  3. Type in: cd %ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32
  4. Type in: notepad Microsoft.Cpp.Win32.targets
  5. Find the “LinkEmbedManifest” target (search for: Target Name="LinkEmbedManifest")
  6. Under the above target and in the task “< Link” perform the following steps.
  7. Change property DelaySign
    • From : DelaySign ="%(Link.DelaySign)"
    • To : DelaySign ="$(LinkDelaySign)"
    • Verify you changed % to $ AND removed the period between Link and Delay.)
  8. Change property KeyFile
    • From : KeyFile ="%(Link.KeyFile)"
    • To: KeyFile ="$(LinkKeyFile)"
    • Verify you changed % to $ AND removed the period between Link and Key.)
  9. Save the changes and exit notepad.
  10. Exit the Command Window by typing in: Exit

Redefine the “Key File” and “Delay Sign” properties used for signing your project:

  1. Get into MS Visual Studio 2010 and open your project.
  2. Right click on your "project" to bring up the properties page.
  3. Go to Configuration Properties->Linker->Advanced
  4. Overwrite the property “Key File” with your original key file. (for e.g. myfile.snk)
  5. Exit the Properties Page.
  6. Save and compile your program.

These steps worked for my project. For more details, go to the link above that Phil provided.

End Edit