如何让 MSBuild 生成与平台无关的 COMReference?

发布于 2025-01-02 20:25:03 字数 883 浏览 3 评论 0原文

我最近将所有测试项目从 dotnet 4 切换到 dotnet 3.5(因为我想在 CLR 2.0 下测试代码(请参阅 此处)。大多数事情都工作正常,但一个测试项目有一个对 IWshRuntimeLibrary 的依赖由以下 csproj 代码片段指定:

<COMReference Include="IWshRuntimeLibrary">
  <Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
  <VersionMajor>1</VersionMajor>
  <VersionMinor>0</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>tlbimp</WrapperTool>
  <Isolated>False</Isolated>
  <EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>

我们将测试项目构建为“AnyCPU”。当测试项目是 .Net 4 时,这似乎会生成 ANYCPU 互操作 dll。 .Net 3.5 中,互操作 dll 为 x86,这会在 64 位平台上运行时导致 System.BadImageFormatException 不会出现此问题。在降级测试项目之前。

I recently switched all our test projects from dotnet 4 to dotnet 3.5 (because I want to test code under CLR 2.0 (see here). Most things work fine, but one test project has a dependency on IWshRuntimeLibrary. This is specified by the following csproj snippet:

<COMReference Include="IWshRuntimeLibrary">
  <Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
  <VersionMajor>1</VersionMajor>
  <VersionMinor>0</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>tlbimp</WrapperTool>
  <Isolated>False</Isolated>
  <EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>

We build the test project as "AnyCPU". When the test project was .Net 4, this seemed to produce an ANYCPU interop dll. Now it's .Net 3.5, the interop dll is x86, which causes a System.BadImageFormatException at runtime on 64 bit platforms. This issue did not occur before downgrading the test projects.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

丿*梦醉红颜 2025-01-09 20:25:03

似乎是正确的,在 Visual Studio 中导入类型库总是会在互操作程序集标头中设置 32 位标志。您可以通过在生成的程序集上运行 corflags.exe 来查看这一点。

不支持从 VS 创建平台无关的互操作库。您必须自己运行 Tlbimp.exe。使用 Visual Studio 命令提示符并导航到您的项目目录。然后运行这个命令:

Tlbimp /machine:Agnostic c:\windows\system32\wshom.ocx

并使用“项目 + 添加引用”、“浏览”选项卡添加对生成的 Interop.IWshRuntimeLibrary.dll 的引用。可以在源代码管理中签入 DLL,COM 接口是一成不变的。将主 EXE 项目上的平台目标设置为 x86 是另一种解决方法。

Seemed is correct, importing the type library in Visual Studio is always going to set the 32-bit flag in the interop assembly header. You can see this by running corflags.exe on the generated assembly.

Creating a platform agnostic interop library from VS isn't supported. You will have to run Tlbimp.exe yourself. Use the Visual Studio Command Prompt and navigate to your project directory. Then run this command:

Tlbimp /machine:Agnostic c:\windows\system32\wshom.ocx

And add a reference to the generated Interop.IWshRuntimeLibrary.dll with Project + Add Reference, Browse tab. It is okay to check-in the DLL in source control, the COM interfaces are cast in stone. Setting the Platform target on your main EXE project to x86 would be another workaround.

酒与心事 2025-01-09 20:25:03

通过在我的 csproj 文件中将 ProcessorArchitecture 属性显式设置为 Agnostic,我能够让 MSBuild 生成与平台无关的 COMReference:

<PropertyGroup>
  <ProcessorArchitecture>Agnostic</ProcessorArchitecture>
</PropertyGroup>

我通过查看 ResolveComReference MSBuild 任务 中Microsoft.Common.CurrentVersion.targets 将此值传递给 tlbimp.exe /机器标志

话虽这么说,我选择使用 Hans Passant 的解决方案,即手动生成 DLL 并将其添加到源代码管理中,因为它对构建服务器友好。

I was able to get MSBuild to generate a platform agnostic COMReference by explicitly setting the ProcessorArchitecture property to Agnostic in my csproj file:

<PropertyGroup>
  <ProcessorArchitecture>Agnostic</ProcessorArchitecture>
</PropertyGroup>

I figured it out by looking at the ResolveComReference MSBuild task in Microsoft.Common.CurrentVersion.targets which passes this value to tlbimp.exe /machine flag.

That being said, I chose to use Hans Passant's solution, i.e. manually generating the DLL and adding it to source control because it is build server friendly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文