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

4

我最近将所有测试项目从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的interop dll。现在它是.Net 3.5,interop dll是x86的,在64位平台上运行时会导致System.BadImageFormatException。在降级测试项目之前,这个问题并没有发生。

我认为不存在所谓的平台不可知的组件引用,我怀疑新的CLR/jitter能够检测到x86依赖性并专门编译为x86以使其正常工作。虽然这只是一种猜测。 - Ben Robinson
2个回答

9
"Seemed"是正确的,使用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也是另一种解决方法。"

这就是我最终所做的事情。我强调了似乎,因为我并不真正确定这是如何工作的。但我可以确认的是,以某种方式,VS2010 dotnet 4测试项目设法让这个工作起来。 - Rob
实际上 - 这可以在测试设置中进行配置。我们最初在64位进程中执行测试,这就是为什么我们遇到问题的原因。 - Rob

0
我能够让MSBuild生成一个平台无关的COMReference,通过在我的csproj文件中明确设置ProcessorArchitecture属性为Agnostic。
<PropertyGroup>
  <ProcessorArchitecture>Agnostic</ProcessorArchitecture>
</PropertyGroup>

我通过查看Microsoft.Common.CurrentVersion.targets中的ResolveComReference MSBuild task并将该值传递给tlbimp.exe /machine flag来解决了这个问题。

话虽如此,我选择使用Hans Passant的解决方案,即手动生成DLL并将其添加到源代码控制中,因为它更适合构建服务器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接