Cannot find sn.exe to sign Assembly

青春壹個敷衍的年華 提交于 2019-11-28 18:33:03
Cam Soper

You need to install the Windows SDK 6.0a, not just the runtime.

If you've installed VS2008, you'll find it's already installed, and sn.exe will be here:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\sn.exe

Otherwise, if you don't have VS2008 installed, you can download the SDK individually here.

The file sn.exe is not available in the SDK. The current version of the SDK is 6.1, perhaps they removed sn.exe in this release.

  • open command prompt
  • type cd \
  • type dir /s sn.exe
  • you will get output something like

    Volume in drive C has no label.

    Volume Serial Number is XXXX-XXXX.

Directory of C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin

11/07/2007  12:01 PM            95,728 sn.exe
              1 File(s)         95,728 bytes

You found the directory :)
if not, there is no sn.exe in your system. Install SDK then.

It's part of the SDK (.NET, or now the Windows SDK)

I'm sure you have your reasons -- and there are definitely plenty cases where SN.exe is unavoidable and/or appropriate (Delay Signing for one). (And I've +1'd the Q and the Accepted A and am not disputing their merit in any way so please disregard this if it doesn't apply in your case)

Note that SN.exe is rarely needed in practice - the wiring in Microft.<lang>.targets that drive the compilers [and AL.exe etc.] all [effectively] take the SignAssembly flag in the .proj file into account and conditionally pass in the key to the compiler(s) etc. so it can do all the work in a single touch of the assembly inline (mainly for perf reasons).

This logic also deals with the distinction between .snk and .pfx keys (which are password protected and get secreted into a Key Container). Depending on which form, there is then either a KeyContainerName or KeyOriginatorFile property resolved by Microsoft.Common.targets in the Runtime directory - Search for ResolveKeySource.

If the reason you need to do a SN is because you've just rewritten an assembly, the same pattern should generally hold, i.e. Mono.Cecil and tools a la PostSharp (I assume, not confirmed) generally also take the same arguments and/or can be made to do the signing inline.


Microsoft.Common.targets excerpt

<Target Name="ResolveKeySource" 
  Condition="$(SignManifests) == 'true' or $(SignAssembly) == 'true'">

  <ResolveKeySource ...
    KeyFile="$(AssemblyOriginatorKeyFile)"
    CertificateFile="$(ManifestKeyFile)"
    SuppressAutoClosePasswordPrompt="$(BuildingInsideVisualStudio)">
      <Output TaskParameter="ResolvedKeyFile" PropertyName="KeyOriginatorFile" ..."/>
      <Output TaskParameter="ResolvedKeyContainer" PropertyName="KeyContainerName" ... "/>

Microsoft.CSharp.targets excerpt

    <Csc  ...
          KeyContainer="$(KeyContainerName)"
          KeyFile="$(KeyOriginatorFile)" />

For completeness, here's how to programmatically infer the SDK path relevant to the target you are compiling (tested on 4.0 but same approach is possible all the way back to 2.0, i.e. Microsoft.Common.targets has processed this data for some time):

<Target Name="ResolveSNToolPath" Condition=" 'true' == '$(SignAssembly)' ">
    <PropertyGroup>
      <_SdkToolsBinDir Condition=" '' == '$(_SdkToolsBinDir)' ">$(TargetFrameworkSDKToolsDirectory)</_SdkToolsBinDir>
      <SNToolPath Condition=" '' == '$(SNToolPath)' ">$(_SdkToolsBinDir)SN.exe</SNToolPath>
    </PropertyGroup>
    <Error Condition=" 'true' == '$(SignAssembly)' AND !EXISTS( '$(SNToolPath)' )"
      Text="In order to resign the assembly, this package requires access to the SN.EXE tool from the Windows Platform SDK, which was not found.

The location derived was &quot;$(SNToolPath)&quot;.

Please either:
1) supply a correct path to your SDK Tools bin directory containing SN.EXE by setting %24(_SdkToolsBinDir) or %24(TargetFrameworkSDKToolsDirectory)
OR
2) supply a correct complete path to your SN.EXE signing tool by setting %24(SNToolPath)" />
  </Target>

For total completeness, here's how you would leverage the outputs of this process to run SN.exe

<Target Name="ResignMyAssembly" Condition="$(SignAssembly) == 'true'">
  <Exec Condition=" '$(KeyContainerName)' != '' " 
    Command="&quot;$(SNToolPath)&quot; -Rca &quot;@(MyAssembly)&quot; &quot;$(KeyContainerName)&quot; " />
  <Exec Condition=" '$(KeyContainerName)' == '' " 
    Command="&quot;$(SlpsSdkProtectSnTool)&quot; -Ra &quot;@(MyAssembly)&quot; &quot;$(KeyOriginatorFile)&quot; " />

For VS2017 path was changed to: C:\Program Files (x86)\Microsoft SDKs\Windows\vX\bin\NETFX X.X.X Tools\.

leppie

Nope, looks like you need the SDK for that :(

FYI, the Runtime itself would not be under C:\Program Files\Microsoft.NET -- all it's files live [only] under C:\Windows\Microsoft.NET\vXXXXXX\

For VS2019 the path is C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools\x64\sn.exe

still now i m unable to use VS command prompt. it showing me message like

** Visual Studio 2017 Developer Command Prompt v15.8.9 ** Copyright (c) 2017 Microsoft Corporation

[vcvarsall.bat] Environment initialized for: 'x64'

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community>where sn.exe INFO: Could not find files for the given pattern(s).

Simply:

In windows (according .net framework version \B8.1A.. changes in the path), go to =>

C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools

Write your sn.exe command:

sn -i D:\XX\MYProject.UI.api\MYProject.Gateway\my_certificate.pfx VS_KEY_AD6FD8AFB39B6C43

if it is password protected than it will want the pwd write it down

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!