1

我需要使用 C# 在 .Net Framework 中创建一个免注册的 COM 对象。

我遵循了MSDN 演练。我必须努力解决它,或者它对我来说不够清楚,或者它不正确,但这是一篇旧帖子,我在 Windows 10 上使用 Visual Studio 2015,所以可能有些地方发生了变化。

以下是我为使其工作而采取的步骤:

  1. 编译COM C# dll SideBySide.dll(Target Framework 2.0),当然我没有regasm注册过。

  2. 我不使用教程中描述的方法,它似乎对我不起作用。我创建SideBySide.Manifestmt.exe,这里是命令:

    mt -outputresource:"<path SidebySide.dll>" -manifest "<SideBySide.manifest>"

  3. 我手动修改了生成的清单以删除所有无用的标签,并添加强制性标签。这是修改后的清单:

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <assemblyIdentity
            name="SideBySide"
            version="1.0.0.0"
            type="win32" />
        <clrClass
            clsid="{4B72FC46-C543-4101-80DB-7777848D1357}"
            progid="SideBySide.SideBySideClass"
            threadingModel="Both"
            name="SideBySide.SideBySideClass"
            runtimeVersion="v2.0.50727">
        </clrClass>
        <file name="SideBySide.dll">
        </file>
    </assembly>
    
  4. 我已经SideBySide.dll用这个命令添加了清单:

    mt -outputresource:"<Path SidebySide.dll>" -manifest "SideBySide.manifest"

  5. 我已经从SideBySide.dll using tlbexp` 导出了 TLB。

  6. 我在 C++ 客户端的配置中设置了No。Properties -> Manifest tool -> Embed Manifest

  7. 我已经编译client.exe,然后我对client.exe.manifest文件应用了更改。这是修改后的清单:

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <assemblyIdentity
            type = "win32"
            name = "client"
            version = "1.0.0.0" />
        <dependency>
            <dependentAssembly>
                <assemblyIdentity
                    type="win32"
                    name="SideBySide"
                    version="1.0.0.0" />
            </dependentAssembly>
        </dependency>
    </assembly>
    

一切运行良好,似乎我可以从本机 C++ 应用程序使用 .Net Framework COM 接口。

但是,当我尝试SideBySide.dll使用 .Net Framework 4.0 或更高版本进行编译时,会出现问题CreateInstance

ISideBySideClassPtr ptr;
HRESULT hr = ptr.CreateInstance(__uuidof(SideBySideClass));

发生此错误:

0x8013101b :此程序集由比当前加载的运行时更新的运行时构建,无法加载。

当然,我已经尝试执行上面列出的所有步骤,我还尝试在 DLL 的清单中指定运行时版本,但它没有用。

我也读过这篇文章。问题是一样的,但我认为该解决方案不适合我,因为我需要从本机客户端调用 C# COM 对象。

是否有一些解决方法可以应用,还是我需要另一种方法来解决我的问题?

4

2 回答 2

2

我有点晚了,但对于遇到这个的其他人来说......

我今天早些时候遇到了这个问题。我的免费注册 COM 库是用 .Net 4.5.2 构建的,我的解决方案是使用“runtimeVersion”属性,如下所示

<clrClass 
   clsid="{...}" 
   progid="Library.Name" 
   threadingModel="Both" 
   name="Library.Name.Class"
   runtimeVersion="v4.0.30319">

或者,您可以省略 runtimeVersion 属性(或指定 v2.0.50272)并为 .Net 3.5 编译您的库。任何一种解决方案似乎都可以解决问题。

于 2017-11-04T00:48:56.190 回答
0

我只是猜测,但是您说清单文件中的运行时版本是 2.0.50727,但是您在使用 4 编译时遇到问题?您的清单和工具的版本不匹配。

我只是使用清单工具在我的程序集中创建和存储信息(在 PostBuild 步骤中):

"$(PathToYourTools)\mt.exe" -managedassemblyname:$(TargetPath) -nodependency -outputresource:$(TargetPath);#2

它的另一个好处是不需要为 .NET 程序集生成类型库。

于 2016-10-11T17:46:05.450 回答