我一直在研究 C# 中的枚举 Windows 便携式设备,其中包括编辑为 PortableDeviceApi COM 对象生成的运行时可调用包装器 (RCW),因为默认的 COM 类型库导入过程导致该GetDevices
方法的编组错误。因此,我遵循了如何:编辑互操作程序集来编辑 RCW,甚至设法建立一个 VS 项目以将其检入源代码并在构建期间按照此处给出的建议生成编辑后的 RCW -是否有编译 CIL 的示例Visual Studio 项目中的代码。
但是,无论我是手动构建自定义 RCW 还是从 VS 项目构建,我都无法让 VS 引用 RCW。以下是“有效”的方法:如果我按照正常程序添加 COM 引用(右键单击项目 > 添加 > COM 引用...),然后选择 PortableDeviceApi,则会将一个COMReference
元素添加到 .csproj:
<COMReference Include="PortableDeviceApiLib">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>0</VersionMinor>
<VersionMajor>1</VersionMajor>
<Guid>1f001332-1a57-4934-be31-affc99f4ee0a</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
并且在项目的 obj 文件夹下添加了自动生成的 Interop.PortableDeviceApiLib.dll RCW。我可以用我从上面提到的编辑过的 MSIL 生成的那个来手动替换这个 DLL,这似乎工作得很好——我得到了 COM 对象的智能感知,以及编辑过的编组更改。这种方法的缺点是我必须将编辑后的 DLL 复制到通过添加 COM 引用生成的 DLL 上,这看起来很不稳定(并且对自动构建管道不太友好)。
我尝试过的另一件事是直接引用 MSIL 项目的输出 DLL。这确实构建成功,但无论出于何种原因,智能感知和对象浏览器都没有获取元数据,因此这不是一个很好的开发人员体验。
最后,如果我尝试将自定义 RCW 的版本信息更改为 v1.1(库存 RCW 为 1.0)并相应地更新上述COMReference.VersionMinor
元素,MSBuild 会抱怨
Warning MSB3284 Cannot get the file path for type library "1f001332-1a57-4934-be31-affc99f4ee0a" version 1.1. Library not registered. (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED))
底层 COM 组件本身已注册。然而,到目前为止,我还没有找到任何关于如何注册 RCW 的信息。
我想接下来我可能会尝试使用混合,使用 MSIL 项目生成自定义 DLL,并使用标准的添加 COM 引用过程来给我智能感知,并在某处放置自定义构建步骤以复制 MSIL 项目的自定义 RCW,其中COMReference
元素会期待它。但在我承诺解决方案之前 -
有没有人成功让 Visual Studio 干净地识别对自定义运行时可调用包装 DLL 的引用?理想情况下,我希望在“添加 COM 引用”对话框中可以使用更新后的 RCW,但这不是绝对要求。