从 C# 和 MC++ 安装和使用并排原生程序集
本文详细介绍了如何创建、安装和使用 C# 和 MC++ 的并排原生程序集。
引言
本文演示了使用原生 dll 进行 Side-By-Side 程序集执行的安装。还演示了如何从 MC++ 中使用这些 sxs 原生 dll。
实现 SxS 程序集
在这里,我将考虑需求 1) 创建一个 MC++ 包装器到原生 dll,以及 2) 从 C# 调用 MC++ 包装器,因为框架是用原生 C++ 构建的。以下是执行此操作的步骤。
1. 创建一个原生 dll,构建一个程序集清单和一个目录文件。
2. 使用 Windows Installer 将原生 dll、清单和目录安装到 WinSxS。
3. 创建一个 MC++ dll,从原生 dll 的清单中提取程序集标识,并将其指定为“链接器选项”下的“附加清单依赖项”属性。对此程序集进行签名并将其放入 GAC。
4. 创建一个 C# 可执行文件 (.exe),并从 GAC 添加对 MC++ 程序集的引用。构建应用程序并运行 C# 可执行文件。
创建清单和目录文件
1. 使用 Visual C++ 创建一个 Win32 或 MFC DLL,并将其命名为“UnmanagedCPP.dll”。
2. 获取一对证书和私钥,例如“mycert.cer”和“mycert.pvk”。作为 WinSxS 的要求,证书密钥必须至少为 2048 位。
makecert -pe -ss MY -$ individual -n ”CN= certificate_name” -len 2048 –r
将 .cer、.pvk 和 .dll 文件存储在同一个文件夹中。
如果提供了具有 2048 位密钥的证书,则将其安装到系统中并导出它,选择“是,导出私钥”选项,然后可以创建并存储一个 .pfx 文件。完成后,可以忽略步骤 7。3. 使用 Visual Studio 2005 命令提示符发出以下命令以从 .cer 证书获取 publicKeyToken
pktextract mycert.cer The output would be as below: 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”
4. 使用记事本创建一个清单文件“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>必须将从上一步提取的公钥令牌插入清单。
5. 清单文件应使用哈希值进行更新,使用以下命令更新
mt.exe -manifest UnmanagedCPP.manifest -hashupdate -makecdfs清单文件“UnmanagedCPP.manifest”将包含 DLL“UnmanagedCPP.dll”的哈希。-makecdfs 选项会生成一个名为“UnmanagedCPP.manifest.cdf”的文件,该文件描述了将用于验证清单的安全目录的内容。
6. 必须生成一个验证目录,执行以下命令生成一个
makecat UnmanagedCPP.manifest.cdf
7. 使用“pvkimprt”实用程序使用“.pvk”和“.cer”文件生成“.pfx”文件
pvkimprt -pfx mycert.cer mycert.pvk将 PFX 格式文件命名为“mycert.pfx”。
8. 使用 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”替换为实际密码。部署共享 Side-By-Side 程序集所需的 3 个文件如下
UnmanagedCPP.dll
UnmanagedCPP.cat
UnmanagedCPP.manifest
创建安装文件
9. 这些文件使用 Windows Installer 部署到 WinSxS• 使用 Visual Studio .Net 创建一个 Setup 项目。将上述 3 个文件添加到项目中并构建项目。
• 使用 Orca 打开构建的 MSI 文件进行进一步编辑。
• “File”表包含 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_”列的原始值)。
• “Component”表包含 3 行。删除“Component”列值对应于文件“UnmanagedCPP.manifest”和“UnmanagedCPP.cat”的 2 行。
• 浏览“FeatureComponent”表,重复步骤 4 并删除“UnmanagedCPP.manifest”和“UnmanagedCPP.cat”文件的多余组件行。
• 浏览“MsiAssembly”表,添加一行
• Component_:值为“File”表,“Component”列中“UnmanagedCPP.dll”、“UnmanagedCPP.manifest”或“UnmanagedCPP.cat”(在步骤 3 之后,这 3 个“Component”列应包含相同的值)
• Feature_:DefaultFeature(这是 Visual Studio 2005/2003 Setup 项目中的唯一功能名称。也可以从“Feature”表或“FeatureComponent”表中找到。)
• File_Manifest:值为“File”表,“File”列中文件“UnmanagedCPP.manifest”的值
• File_Application
• Attribute:1
• 浏览“MsiAssemblyName”表,添加 5 行,“Component_”列均采用“File”表,“Component”列中“UnmanagedCPP.dll”的值。5 行的“Name”列和“Value”列取自清单文件内容
名称 ----- 值
type: win32
name: UnManagedCPP
version: 1.0.0.0
processorArchitecture: x86
publicKeyToken: 4b762499fc143588• 保存 MSI 文件并退出 Orca。此更新的 MSI 文件应能够将“UnmanagedCPP.dll”作为 side by side 共享程序集安装到 WinSxS 文件夹。
创建引用原生 dll 的 MC++ dll
10. 使用 UnmanagedCPP.lib 和 UnmanagedCPP.h 创建 ManagedCPP.dll,并在链接器选项下指定附加清单引用属性,其中包含 UnmanagedCPP.manifest 的程序集标识。对 ManagedCpp.dll 进行签名并将其安装到 GAC。创建引用 MC++ dll 的 C# 代码
11. 创建 CSharp.exe,它引用 ManagedCPP.dll。注意:为了生成清单文件,可以使用任何可用的工具,因为它们易于使用和配置,可以构建合适的清单文件类型。