我在使用 Visual Studio 2022 注册用于 COM 互操作的 C# 组件时遇到困难。我以为我理解了这个问题,但即便如此,我也没能让它工作。
这是基本问题:
由于现实世界中大多数基于 COM 的应用程序都是 32 位应用程序,因此这很可能不是您想要的。
虽然这显然是设计使然,但我发现这是一个不幸的设计选择,我已经在开发者社区中提出了一个问题。如果您同意我的观点,可能会对这个问题投赞成票。
尝试的解决方法:
按照此页面上的说明进行操作我认为通过以下方式更新我们的项目会很容易:
这是我定义为构建后事件的命令:
"%Windir%Microsoft.NET\Framework\v4.0.30319\regasm.exe” “$(TargetPath)” /codebase
这会导致错误 MSB3073 和文本“命令...退出,代码为 123”。
完整的输出行是:
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets(5710,5): error MSB3073: The command ""%Windir%Microsoft.NET\Framework\v4.0.30319\regasm.exe” “C:\CS3\Output\Applications\interop\McDaMBusTimer.dll” /codebase" exited with code 123.
我尝试了该命令的几种变体,但我还没有找到有效的定义。
有人知道我作为构建后步骤必须输入的确切命令吗?
这个错误非常愚蠢,完全是我自己的错。
正确的命令是
"%windir%\Microsoft.NET\Framework\v4.0.30319\regasm.exe" "$(TargetPath)" /codebase
如果需要生成类型库文件,应该使用命令
"%windir%\Microsoft.NET\Framework\v4.0.30319\regasm.exe" "$(TargetPath)" /codebase /tlb
如果想直接编辑到工程文件中,可以使用
<PropertyGroup>
<PostBuildEvent>"%25windir%25\Microsoft.NET\Framework\v4.0.30319\regasm.exe" "$(TargetPath)" /codebase /tlb</PostBuildEvent>
</PropertyGroup>
正如 Simon Mourier 指出的那样,我最初使用了错误的引号。原来我正在使用 右双引号,Unicode 0x201D 而不是 正常 引号,Unicode 0x0022.
在我看来,您在 Visual Studio 中看不到项目属性的差异。
我出现此错误的原因是我最初复制了命令
“%Windir%Microsoft.NETFramework[64]v4.0.xxxxxregasm” “$(TargetPath)”
来自此 Microsoft 页面。如果你仔细观察,你会发现差异。
更优雅的解决方案是使用值为
RegisterAssemblyMSBuildArchitecture
的 MSBuild x86
属性来强制 COM 程序集注册任务(或 regasm
)在 32 位注册表中注册项目的程序集。如果要强制 64 位 COM 程序集注册,请使用 x64
值作为 RegisterAssemblyMSBuildArchitecture
。我将值为 RegisterAssemblyMSBuildArchitecture
的 x86
属性添加到我的项目文件中并且它起作用了。该程序集现已在 32 位注册表项中注册,而不是在 64 位注册表项中注册。
显然,如果
Platform
MSBuild 属性为 AnyCPU
,就会发生这种情况。在这种情况下,COM 程序集注册默认为与 MSBuild 运行时相同的位数。对于 Visual Studio 2022,这意味着 64 位 MSBuild 运行时。如果 Platform
为 x86
,则 COM 程序集注册也将为 32 位,而无需设置 RegisterAssemblyMSBuildArchitecture
属性。我无法确认这一点,因为我还没有尝试过这种方法。
原始问题中链接的 Microsoft 开发人员社区错误报告中的问题解决方案指出了这一点。
据我所知,
RegisterAssemblyMSBuildArchitecture
在其他地方没有记录。