我们正在开发一个引用一些COM库的C#应用程序(例如AutoIT)。
我在源代码管理下将所有引用的组件包含在第三方“Libs”文件夹中。
问题是COM dll在.csproj文件中没有HintPath属性,我认为必须使用regsvr32(或使用某种脚本)手动注册这些属性。
我目前正在研究创建一个在每次构建之前运行的MSBuild脚本,但是我无法弄清楚我是应该手动调用regsvr32.exe还是使用一些预定义的MSBuild任务?
目前,这是我作为测试所支持的内容:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<ItemGroup>
<MyAssemblies Include="D:\*.dll" />
</ItemGroup>
<Target Name="Build">
<RegisterAssembly
Assemblies="@(MyAssemblies)" >
</RegisterAssembly>
</Target>
</Project>
这会生成我在给定文件夹中放置的DLL不是有效DLL的错误。
这个问题的解决方案是什么?
编辑:
引用COM dll的项目在.csproj文件中有类似的内容:
<COMReference Include="AutoItX3Lib">
<Guid>{F8937E53-D444-4E71-9275-35B64210CC3B}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
</COMReference>
这不包括任何提示路径作为其他托管程序集,因此在构建服务器上,找不到引用的COM dll。
使用REGSVR32在构建服务器上注册COM dll时,构建成功。
答案 0 :(得分:13)
对于我对类似问题的原始回答,请参阅:TFS Build server and COM references - does this work?
构建服务器的更好选择可能是使用项目文件中的COMFileReference
项而不是COMReference
。一个例子如下:
<ItemGroup>
<COMFileReference Include="MyComLibrary.dll">
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMFileReference>
</ItemGroup>
无需在机器上注册COM dll即可使用。
每个COMFileReference项也可以有一个WrapperTool属性,但默认似乎工作正常。 EmbedInteropTypes属性未记录为适用于COMFileReference,但它似乎按预期工作。
有关详细信息,请参阅https://docs.microsoft.com/en-ca/visualstudio/msbuild/common-msbuild-project-items#comfilereference。自.NET 3.5以来,此MSBuild项已可用。
答案 1 :(得分:11)
您不在构建服务器上注册COM服务器。只有在您真正想要运行编译的代码时才需要这样做。您需要的是COM服务器的类型库,以便您可以获得互操作程序集。您使用Tlbimp.exe创建的。
您是想在构建服务器上运行Tlbimp还是在开发机器上预先运行Tlbimp,这在很大程度上取决于您如何部署这些COM服务器。保持COM可执行文件和.tlb文件的副本非常靠近您的互操作库是一个好主意。换句话说,检查它们。安装程序现在也可以检索已知良好版本的COM服务器。
答案 2 :(得分:0)
1)尝试将COM库引用到csproj作为参考 - 如果你还没有这样做。
2)尝试附加到您的csproj文件:
<Project ... >
...
<Target Name="BeforeBuild">
<Exec Command="regsvr32.exe yourComponent.dll" />
</Target>
</Project>
PS:如果您使用的是某种构建服务器软件,则不应修改csproj,而应修改服务器上构建使用的脚本。
答案 3 :(得分:0)
我不确定,如果MSBuild中有任何任务,调用regsvr32,但REgisterAssembly正在调用regasm.exe - 即为COM互操作注册.NET组件。
我确信,手动调用regsvr32将是获得所需结果的最快方法。
另一件事是 - 如果COM DLL已经被先前版本注册并且您将再次运行构建脚本会发生什么? (我真的不知道regsvr32会如何反应,只是想到这里)