除了调用命令行向程序集添加强名称之外,是否有任何 API 可以让您在程序集被剥夺其强名称后退出该程序集?
2 回答
这取决于您所说的“剥夺其强名称”的程序集是什么意思。如果程序集没有强命名,则在使用强名称重新构建程序集之前,没有任何东西(甚至 sn.exe)可以退出程序集。
但要回答您的问题:所有强命名功能都通过 CLR 的非托管强命名 API公开。具体来说,您需要StrongNameSignatureGenerationEx
,正如您会注意到的那样,它在功能上等同于sn -R[a]
命令。
话虽如此sn.exe
,调用自身要简单得多。访问非托管强名称 API 并不适合胆小的人,因为(从 .NET 4 开始)您必须首先通过 CLR 的元托管 API。出于这个原因,您也几乎不得不完全在非托管代码中执行此操作。(我确实在 CodePlex 上找到了 Microsoft 的托管包装器,但我无法StrongNameSignatureGenerationEx
通过它正常工作。)
但是,如果您必须这样做,以下是如何从非托管代码访问强命名 API 的粗略概述:
- 通过调用来获取
ICLRMetaHost
或的实例。ICLRMetaHostPolicy
CLRCreateInstance
- 使用该实例,获取当前运行时的实例(即
ICLRRuntimeInfo
实例)。有很多方法可以做到这一点;有关血腥细节,请参阅MSDN。 - 一旦有了 的实例,就可以通过调用的方法
ICLRRuntimeInfo
获取 的实例,传入和用于类/接口标识符。ICLRStrongName
ICLRRuntime
GetInterface
CLSID_CLRStrongName
IID_ICLRStrongName
现在你有了一个 的实例ICLRStrongName
,你终于可以StrongNameSignatureGenerationEx
使用它来调用了:
// This is the ICLRStrongName instance you'll need. Assume GetStrongNameAPI
// corresponds to an implementation of the rough process I outlined above.
ICLRStrongName *snAPI = GetStrongNameAPI();
// You'll have to load the .snk file into memory yourself using the Win32
// file APIs, the details of which I've omitted for the sake of brevity.
BYTE *keyPairBlob = NULL;
DWORD keyPairBlobSize = 0;
LoadKeyPair(&keyPairBlob, &keyPairBlobSize);
// Once you've got the key pair blob, you can now (re-)sign the assembly
HRESULT hr = snAPI->StrongNameSignatureGenerationEx(
L"path\\to\\your\\assembly.dll",
NULL,
keyPairBlob,
keyPairBlobSize,
NULL,
NULL,
0
);
// Do whatever error handling needs to be done with the given HRESULT
(或者,如果您想使用密钥容器而不是.snk
密钥对进行签名,您可以将密钥容器的名称作为第二个参数传入,并将密钥对 blob/大小参数保留为 NULL。)
底线:如您所见,除非您真的必须通过强大的命名 API,否则仅通过调用 sn.exe 本身来(重新)签署程序集要容易得多。
您可以查看mscoree
's strong name APIs,但我不推荐它。