【问题标题】:.NET Core 6.0 COM interoperability issues with Python/Octave.NET Core 6.0 COM 与 Python/Octave 的互操作性问题
【发布时间】:2022-02-10 19:55:42
【问题描述】:

我目前正在尝试在 .NET Core 6 中创建一个 COM 对象。为此,我制作了一个类库并像这样编辑了项目:

C#:

项目文件(*.csproj):

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <EnableComHosting>true</EnableComHosting>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>
    
</Project>

COM 对象 (*.cs):

using System;
using System.Runtime.InteropServices;

namespace COMNetCore6
{
    [ComVisible(true)]
    [Guid("64D6F9F6-6163-401A-82E6-C941CAF01399")]
    [ProgId("HelloWorldCOMObject")]
    public class ComObject
    {
        public string SayHello() => "Hello world from .NET Core";
    }
}

构建项目后,我得到一个 *.comhost.dll 文件,我可以使用命令“regsvr32 *.comhost.dll”将其添加到注册表中。 comhost.dll 注册成功并且它在 Excel 中按预期工作于 Visual Basic

当我尝试在另一种编程语言中使用这个 COM 对象时,虽然它不起作用。我尝试过使用 Octave 和 Python。虽然 Octave 只告诉我它无法创建服务器,但 Python 至少给了我这个错误:

Python:

>>> import win32com.client
>>> comobj = win32com.client.Dispatch("HelloWorldCOMObject")
Traceback (most recent call last):
  File "C:\*\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\dynamic.py", line 86, in _GetGoodDispatch
    IDispatch = pythoncom.connect(IDispatch)
pywintypes.com_error: (-2147221021, 'Operation unavailable', None, None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\*\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\__init__.py", line 117, in Dispatch
    dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch, userName, clsctx)
  File "C:\*\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\dynamic.py", line 106, in _GetGoodDispatchAndUserName
    return (_GetGoodDispatch(IDispatch, clsctx), userName)
  File "C:\*\AppData\Local\Programs\Python\Python39-32\lib\site-packages\win32com\client\dynamic.py", line 88, in _GetGoodDispatch
    IDispatch = pythoncom.CoCreateInstance(
pywintypes.com_error: (-2147467262, 'No such interface supported', None, None)

我已尝试按照这些链接中描述的步骤(尤其是第一个)并根据我的需要调整它们来解决这个问题:

Can I connect a .NET 5 COM interop object with VB6? https://github.com/GregReddick/ComTestLibrary/tree/master/ComTestLibrary1 https://docs.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com

不幸的是,我尝试过的方法都没有奏效。我试图为 COM 对象创建一个接口并在 C# 中使用正确的互操作性注释,但错误仍然存​​在。正如我所说的,虽然没有接口且上面几乎没有任何注释的基本方法适用于 Visual Basic。

在这种情况下,我尝试在没有 TLB(类型库)的情况下使用后期绑定,因为我需要它同时用于后期绑定(没有 TLB)和早期绑定(使用 TLB),我决定从后期绑定开始。

关于后期绑定方法有一个类似的问题,目前尚未得到解答:'No such interface supported' when using .NET 6.0 COM object in python 3.9

由于 COM 对象适用于 Visual Basic,但不适用于其他编程语言,我不确定究竟是什么导致了这个问题。

【问题讨论】:

  • 我会尝试查找对象 excel 的类型。尝试在 excel 中获取类型,这可能会提供线索为什么它在其他情况下不起作用。在返回对象的地方设置一个断点并查看类型。

标签: python c# com language-interoperability


【解决方案1】:

.NET Core 包装器不支持在创建 COM 对象的同时请求 IDispatch 的这种类型的调用:

C/C++:

IDispatch* disp;
CoCreateInstance(YourCLSID, NULL, CLSCTX_ALL, IID_IDispatch, &disp); // fails

Python:

disp = pythoncom.CoCreateInstance(YourCLSID, None, pythoncom.CLSCTX_ALL, pythoncom.IID_IDispatch) // fails

您必须首先获得 IUnknown 引用和 IDispatch 的 QI,就像在 python 中一样(这是 Excel/VBA 所做的):

import pythoncom
import pywintypes
from win32com.client import Dispatch

unk = pythoncom.CoCreateInstance(pywintypes.IID('{64D6F9F6-6163-401A-82E6-C941CAF01399}'), None, pythoncom.CLSCTX_ALL, pythoncom.IID_IUnknown)
disp = Dispatch(unk.QueryInterface(pythoncom.IID_IDispatch))
print disp.SayHello

恕我直言,应该修改 python COM 支持以始终执行此操作...

【讨论】:

  • 您是否有指向解释 COM 包装器从 .NET Framework 到 .NET (Core) 6.0 的确切更改的源的链接?我对这个问题是如何发生的很感兴趣。
  • 不幸的是,没有单一来源...您有旧的 .NET Framework 文章(您必须自己理解它们是旧的),新的 .NET 核心文章(和 . NET Core 3.1 与 .NET 5 和 6 不同),您必须弄清楚真正发生了什么变化……或者您可以深入研究 dotnet 源代码(祝您好运)。需要记住的一件事是,Microsoft 尽可能从运行时中删除了 COM 支持,并添加了作为外部包的支持(如 C#/WinRT 等),以实现“更好的”跨平台支持。这引起了很多麻烦和破坏性变化......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多