6

除了调用命令行向程序集添加强名称之外,是否有任何 API 可以让您在程序集被剥夺其强名称后退出该程序集?

4

2 回答 2

3

这取决于您所说的“剥夺其强名称”的程序集是什么意思。如果程序集没有强命名,则在使用强名称重新构建程序集之前,没有任何东西(甚至 sn.exe)可以退出程序集。

但要回答您的问题:所有强命名功能都通过 CLR 的非托管强命名 API公开。具体来说,您需要StrongNameSignatureGenerationEx,正如您会注意到的那样,它在功能上等同于sn -R[a]命令。

话虽如此sn.exe,调用自身要简单得多。访问非托管强名称 API 并不适合胆小的人,因为(从 .NET 4 开始)您必须首先通过 CLR 的元托管 API。出于这个原因,您也几乎不得不完全在非托管代码中执行此操作。(我确实在 CodePlex 上找到了 Microsoft 的托管包装器,但我无法StrongNameSignatureGenerationEx通过它正常工作。)

但是,如果您必须这样做,以下是如何从非托管代码访问强命名 API 的粗略概述:

  • 通过调用来获取ICLRMetaHost或的实例。ICLRMetaHostPolicyCLRCreateInstance
  • 使用该实例,获取当前运行时的实例(即ICLRRuntimeInfo实例)。有很多方法可以做到这一点;有关血腥细节,请参阅MSDN
  • 一旦有了 的实例,就可以通过调用的方法ICLRRuntimeInfo获取 的实例,传入和用于类/接口标识符。ICLRStrongNameICLRRuntimeGetInterfaceCLSID_CLRStrongNameIID_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 本身来(重新)签署程序集要容易得多。

于 2010-10-11T01:28:48.957 回答
2

您可以查看mscoree's strong name APIs,但我不推荐它。

于 2009-03-28T10:59:35.100 回答