Я уверен, что у вас есть свои причины - и, безусловно, существует множество случаев, когда SN.exe
неизбежен и / или уместен (задержка подписания для одного). (И у меня +1 к Q и Принято A, и я не оспариваю их достоинства, поэтому не обращайте на это внимания, если это не применимо в вашем случае)
Обратите внимание, что на практике SN.exe
редко требуется - проводка в Microft.<lang>.targets
, которая управляет компиляторами [и AL.exe
и т. Д.], Все [эффективно] учитывает флаг SignAssembly
в файле .proj и условно передать ключ компилятору (компиляторам) и т. д., чтобы он мог выполнять всю работу одним касанием встроенной сборки (в основном по соображениям производительности).
Эта логика также касается различия между ключами .snk
и .pfx
(которые защищены паролем и секретируются в контейнер ключей). В зависимости от того, какая форма, тогда существует либо свойство KeyContainerName
, либо KeyOriginatorFile
, разрешенное с помощью Microsoft.Common.targets
в каталоге времени выполнения - поиск ResolveKeySource
.
Если причина, по которой вам нужно сделать SN
, заключается в том, что вы только что переписали сборку, то, как правило, должен сохраняться один и тот же шаблон, то есть Mono.Cecil
и инструменты a la PostSharp (я полагаю, не подтвержденные), как правило, также принимают те же аргументы и / или могут быть использованы для выполнения подписи inline.
Выдержка Microsoft.Common.targets
<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 выдержка
<Csc ...
KeyContainer="$(KeyContainerName)"
KeyFile="$(KeyOriginatorFile)" />
Для полноты, вот как программно сделать вывод пути SDK, относящегося к цели, которую вы компилируете (протестировано на 4.0, но такой же подход возможен вплоть до 2.0, т.е. Microsoft.Common.targets
обработал эти данные в течение некоторого времени):
<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 "$(SNToolPath)".
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>
Для полной полноты вот как можно использовать выходные данные этого процесса для запуска SN.exe
<Target Name="ResignMyAssembly" Condition="$(SignAssembly) == 'true'">
<Exec Condition=" '$(KeyContainerName)' != '' "
Command=""$(SNToolPath)" -Rca "@(MyAssembly)" "$(KeyContainerName)" " />
<Exec Condition=" '$(KeyContainerName)' == '' "
Command=""$(SlpsSdkProtectSnTool)" -Ra "@(MyAssembly)" "$(KeyOriginatorFile)" " />