如何让 MSBuild 生成与平台无关的 COMReference?
我最近将所有测试项目从 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
似乎是正确的,在 Visual Studio 中导入类型库总是会在互操作程序集标头中设置 32 位标志。您可以通过在生成的程序集上运行 corflags.exe 来查看这一点。
不支持从 VS 创建平台无关的互操作库。您必须自己运行 Tlbimp.exe。使用 Visual Studio 命令提示符并导航到您的项目目录。然后运行这个命令:
并使用“项目 + 添加引用”、“浏览”选项卡添加对生成的 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:
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.
通过在我的 csproj 文件中将 ProcessorArchitecture 属性显式设置为 Agnostic,我能够让 MSBuild 生成与平台无关的 COMReference:
我通过查看 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 toAgnostic
in my csproj file: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.