在本文中,将探讨如何创建一个MC++包装器来调用原生DLL,并从C#中调用这个MC++包装器,因为框架是建立在原生C++之上的。以下是实现此目标的步骤:
首先,需要创建一个原生DLL,构建一个程序集清单和一个目录文件。以下是详细步骤:
1. 创建一个Win32或MFC DLL,使用Visual C++,并将其命名为“UnmanagedCPP.dll”。
2. 获取一对证书和私钥,例如“mycert.cer”和“mycert.pvk”。对于WinSxS的要求,证书密钥至少必须是2048位。
makecert -pe -ss MY -$ individual -n "CN=certificate_name" -len 2048 -r
3. 将.cer、.pvk和.dll文件存储在同一个文件夹中。如果已有2048位密钥的证书,则将其安装到系统中并导出,选择“是,导出私钥”选项,然后可以创建并存储.pfx文件。完成此步骤后,可以忽略步骤7。
4. 使用Visual Studio 2005命令提示符,执行以下命令以从.cer证书获取publicKeyToken:
pktextract mycert.cer
输出将如下所示:
Microsoft® Side-By-Side Public Key Token Extractor
1.1.3.0 Copyright (C) Microsoft Corporation 2000-2002. All Rights Reserved
Certificate:
"CATry-Catch" - 2048 bits long
publicKeyToken="4b762499fc143588"
5. 使用记事本创建一个清单文件"UnmanagedCPP.manifest",内容如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="UnmanagedCPP" version="1.0.0.0" processorArchitecture="x86" publicKeyToken="4b762499fc143588"/>
<file name="UnmanagedCPP.dll" hashalg="SHA1"/>
</assembly>
从上一步提取的public key token需要插入到清单中。
6. 使用以下命令更新清单文件的哈希值:
mt.exe -manifest UnmanagedCPP.manifest -hashupdate -makecdfs
清单文件“UnmanagedCPP.manifest”将包含DLL“UnmanagedCPP.dll”的哈希值。
-makecdfs选项生成一个名为“UnmanagedCPP.manifest.cdf”的文件,描述了将用于验证清单的安全目录的内容。
7. 必须构建一个验证目录,执行以下命令构建一个:
makecat UnmanagedCPP.manifest.cdf
8. 使用“pvkimprt”实用程序使用“.pvk”和“.cer”文件生成一个“.pfx”文件:
pvkimprt -pfx mycert.cer mycert.pvk
将PFX格式文件命名为“mycert.pfx”。
9. 使用SignTool使用证书签名目录,如下所示:
signtool sign /f mycert.pfx /p password_for_private_key /du http://www.mycompany.com/MySampleAssembly /t http://timestamp.verisign.com/scripts/timstamp.dll UnmanagedCPP.cat
请将"password_for_private_key"替换为实际密码。
部署共享边侧程序集所需的3个文件如下:
UnmanagedCPP.dll
UnmanagedCPP.cat
UnmanagedCPP.manifest
9. 这些文件使用Windows Installer部署到WinSxS:
• 使用Visual Studio .Net创建一个安装项目。将上述3个文件添加到项目中并构建项目。
• 使用Orca打开构建的MSI文件以进行进一步编辑。
• “文件”表包含3行,每行的“FileName”列指向上述3个文件中的一个,分别是“UnmanagedCPP.dll”,“UnmanagedCPP.cat”和“UnmanagedCPP.manifest”。必须编辑“UnmanagedCPP.cat”和“UnmanagedCPP.manifest”的行,通过替换它们的“Component_”列值,使用“UnmanagedCPP.dll”行的“Component_”列值。这有效地将3个文件分配到原本由“UnmanagedCPP.dll”使用的同一个组件中。请记下2个组件名称(例如,从“UnmanagedCPP.manifest”和“UnmanagedCPP.cat”行的“Component_”列的原始值)。
• “组件”表包含3行。删除2行,其“Component”列值对应于文件“UnmanagedCPP.manifest”和“UnmanagedCPP.cat”。
• 浏览“FeatureComponent”表,重复步骤4并删除“UnmanagedCPP.manifest”和“UnmanagedCPP.cat”文件的不必要组件行。
• 浏览“MsiAssembly”表,添加一行:
Component_: 从“文件”表,“组件”列中获取的值,用于“UnmanagedCPP.dll”,“UnmanagedCPP.manifest”或“UnmanagedCPP.cat”(这3个“Component”列在步骤3之后应该包含相同的值)
Feature_: DefaultFeature(这是Visual Studio 2005/2003安装项目中唯一的特性名称。也可以从“特性”表或“FeatureComponent”表中找到。)
File_Manifest: 从“文件”表,“文件”列中获取的值,用于文件“UnmanagedCPP.manifest”
File_Application:
Attribute: 1
• 浏览“MsiAssemblyName”表,添加5行,其“Component_”列值都是从“文件”表,“组件”列中获取的值,用于“UnmanagedCPP.dll”。这5行的“Name”列和“Value”列值来自清单文件的内容:
Name ----- Value
type: win32
name: UnManagedCPP
version: 1.0.0.0
processorArchitecture: x86
publicKeyToken: 4b762499fc143588
• 保存MSI文件并退出Orca。这个更新后的MSI文件应该能够将“UnmanagedCPP.dll”作为边侧共享程序集安装到WinSxS文件夹中。