从未通过 C# 注册C++ COM 服务器访问 COM 接口

Accessing COM Interface from C++ COM Server that doesn't register via C#

本文关键字:COM 服务器 访问 接口 C++ 注册      更新时间:2023-10-16

我被要求与已经发货的产品集成,该产品是COM服务器。与此产品一起提供了.tlb文件。我已经使用 tlbimp 将TLB导出到主汇编,并且我将其包括在我的C#项目中。当我尝试执行我的COM客户端时,我会收到"未找到接口"错误,因为该应用程序从未在注册表中注册其Typelib。我试图根据MSDN文档运行" server.exe/regserver"。它执行但似乎没有更新或在注册表中添加任何内容。

我能够通过强迫Typelib通过 regtlibv12.exe 进行注册,从而解决了这个问题,但是我在此站点上阅读了该可执行文件不一致的情况并可能被弃用。

link还说,关于regtlibv12.exe:

这是不注册其类型库的COM服务器的解决方法。与上述类似,但是注册类型库是可选的,通常仅在开发机器上,而不需要在运行服务器的计算机上。

如果服务器注册是选项,那么我似乎找不到解决方案的方法。我已经尝试通过System.Runtime.InterOpservices手动定义C#类中的接口,但是除非在注册表中定义了来自TLB的库中的库中,否则它仍然不起作用。

因此,是否有一种方法可以在C#中未注册(并且我没有代码)的COM服务器,而无需执行某些应用程序来强制迫使要注册的TLB?

编辑:这是从TLB导出的IDL I通过 oleview 。根UUID在注册表的Typelib部分中作为主要的互动组件找到(我假设是由于TLBIMP调用),但是库项目本身在任何地方都没有任何参考。搜索注册表中的混凝土类或界面UUID返回空白。

        [
      uuid(C8CF03E5-FD1F-11D3-8C03-0080C8D3C5D3),
      version(1.0),
      custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 100663657),
      custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1153317527),
      custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, "Created by MIDL version 6.00.0361 at Wed Jul 19 09:58:45 2006
    ")
    ]
    library EFilm
    {
        // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
        importlib("stdole2.tlb");
        // Forward declare all types defined in this typelib
        dispinterface IEFilm;
        [
          uuid(C8CF03E6-FD1F-11D3-8C03-0080C8D3C5D3)
        ]
        dispinterface IEFilm {
            properties:
            methods:
                [id(0x00000001)]
                VARIANT_BOOL oleOpenStudy(
                                BSTR strPatientID, 
                                BSTR strAccessionNo, 
                                VARIANT_BOOL bCloseCurWindow, 
                                VARIANT_BOOL bAddToWindow, 
                                short nSeriesRows, 
                                short nSeriesCols, 
                                short nImageRows, 
                                short nImageCols, 
                                VARIANT_BOOL bAutoSeriesFormat, 
                                VARIANT_BOOL bAutoImageFormat);
                [id(0x00000002)]
                VARIANT_BOOL oleShowMainWindow(long nCmdShow);
                [id(0x00000003)]
                VARIANT_BOOL oleShowSearchWindow(long nCmdShow);
                [id(0x00000004)]
                VARIANT_BOOL olePositionMainWindow(
                                short left, 
                                short top, 
                                short right, 
                                short bottom);
                [id(0x00000005)]
                VARIANT_BOOL oleSetForegroundWindow();
                [id(0x00000006)]
                VARIANT_BOOL oleOpenSearchRemote(
                                BSTR strPatientID, 
                                BSTR strAccessionNo);
                [id(0x00000007)]
                VARIANT_BOOL oleOpenStudy2(
                                BSTR strPatientID, 
                                BSTR strAccessionNo, 
                                VARIANT_BOOL bCloseCurWindow, 
                                VARIANT_BOOL bAddToWindow, 
                                short nSeriesRows, 
                                short nSeriesCols, 
                                short nImageRows, 
                                short nImageCols, 
                                VARIANT_BOOL bAutoSeriesFormat, 
                                VARIANT_BOOL bAutoImageFormat, 
                                BSTR strImageSource);
                [id(0x00000008)]
                VARIANT_BOOL oleCloseAllWindows();
                [id(0x00000009)]
                VARIANT_BOOL oleCloseCurrentWindow();
                [id(0x0000000a)]
                VARIANT_BOOL oleOpenStudy3(
                                BSTR strPatientID, 
                                BSTR strAccessionNo, 
                                BSTR strStudyInstanceUID, 
                                VARIANT_BOOL bCloseCurWindow, 
                                VARIANT_BOOL bAddToWindow, 
                                short nSeriesRows, 
                                short nSeriesCols, 
                                short nImageRows, 
                                short nImageCols, 
                                VARIANT_BOOL bAutoSeriesFormat, 
                                VARIANT_BOOL bAutoImageFormat, 
                                BSTR strImageSource);
                [id(0x0000000b)]
                VARIANT_BOOL oleSearch(
                                BSTR searchParams, 
                                VARIANT* searchResults, 
                                BSTR lpszImageSource);
                [id(0x0000000c)]
                VARIANT_BOOL oleOpenSearch(
                                BSTR strPatientID, 
                                BSTR strAccessionNo, 
                                BSTR lpszImageSource);
                [id(0x0000000d)]
                VARIANT_BOOL oleLoginViaDomain(
                                BSTR strUsername, 
                                BSTR strPassword, 
                                BSTR strDomainName);
                [id(0x0000000e)]
                VARIANT_BOOL oleLoginViaFusion(
                                BSTR strUsername, 
                                BSTR strPassword, 
                                BSTR strWSDLFile);
                [id(0x0000000f)]
                VARIANT_BOOL oleLoginViaFusionWithToken(
                                BSTR strUsername, 
                                BSTR strToken, 
                                BSTR strWSDLFile);
                [id(0x00000010)]
                VARIANT_BOOL oleSaveCurrentUserProfile();
                [id(0x00000011), helpstring("method oleOpenStudy4")]
                VARIANT_BOOL oleOpenStudy4(
                                BSTR strOpenStudyInfoXML, 
                                VARIANT_BOOL bCloseCurWindow, 
                                VARIANT_BOOL bFindRelatedStudies, 
                                unsigned long nNumPriors, 
                                BSTR strProtocolListXML);
                [id(0x00000012), helpstring("method oleExportAsBitmap")]
                VARIANT_BOOL oleExportAsBitmap(
                                BSTR destinationDirectory, 
                                short bitmapFormat);
                [id(0x00000013), helpstring("method oleLogout")]
                VARIANT_BOOL oleLogout();
                [id(0x00000014), helpstring("method oleOpenStudy5")]
                VARIANT_BOOL oleOpenStudy5(
                                BSTR strOpenStudyInfoXML, 
                                short nRows, 
                                short nCols, 
                                short nImageRows, 
                                short nImageColumns, 
                                VARIANT_BOOL bShowStudyManager, 
                                VARIANT_BOOL bCloseCurWindow, 
                                VARIANT_BOOL bFindRelatedStudies, 
                                unsigned long nNumPriors, 
                                VARIANT_BOOL bApplyHP, 
                                BSTR strProtocolListXML);
                [id(0x00000015), helpstring("method oleLock")]
                VARIANT_BOOL oleLock();
                [id(0x00000016), helpstring("method oleUnlock")]
                VARIANT_BOOL oleUnlock();
                [id(0x00000017), helpstring("method oleIsLocked")]
                VARIANT_BOOL oleIsLocked();
                [id(0x00000018), helpstring("method oleSelectServers")]
                VARIANT_BOOL oleSelectServers(
                                BSTR strImageSourceGUID, 
                                BSTR strServerList);
        };
        [
          uuid(C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3)
        ]
        coclass Document {
            [default] dispinterface IEFilm;
        };
    };

edit2:

我已经加载了VM并跟踪了更改。在初始服务器自我注册期间,发生的唯一注册是:

    [HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}]
@="EFilm Document"
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}AuxUserType]
@=""
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}AuxUserType2]
@="EFilm"
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}AuxUserType3]
@="eFilm"
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}DefaultIcon]
@="C:\PROGRA~1\MERGEH~1\eFilm\eFilm.exe,1"
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}InprocHandler32]
@="ole32.dll"
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}Insertable]
@=""
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}LocalServer32]
@="C:\PROGRA~1\MERGEH~1\eFilm\eFilm.exe"
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}MiscStatus]
@="32"
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}ProgId]
@="EFilm.Document"
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}verb]
@=""
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}verb]
@="&Edit,0,2"
[HKEY_CLASSES_ROOTCLSID{C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3}verb1]
@="&Open,0,2"

当我执行 regtlibv12.exe 时,它添加了以下注册表条目:

    [HKEY_LOCAL_MACHINESOFTWAREClassesTypeLib{C8CF03E5-FD1F-11D3-8C03-0080C8D3C5D3}1.0]
@="EFilm"
[HKEY_LOCAL_MACHINESOFTWAREClassesTypeLib{C8CF03E5-FD1F-11D3-8C03-0080C8D3C5D3}1.0FLAGS]
@="0"
[HKEY_LOCAL_MACHINESOFTWAREClassesTypeLib{C8CF03E5-FD1F-11D3-8C03-0080C8D3C5D3}1.0win32]
@="C:\eFilm\eFilm.tlb"
[HKEY_LOCAL_MACHINESOFTWAREClassesTypeLib{C8CF03E5-FD1F-11D3-8C03-0080C8D3C5D3}1.0HELPDIR]
@="C:\eFilm"
[HKEY_LOCAL_MACHINESOFTWAREClassesInterface{C8CF03E6-FD1F-11D3-8C03-0080C8D3C5D3}]
@="IEFilm"
[HKEY_LOCAL_MACHINESOFTWAREClassesInterface{C8CF03E6-FD1F-11D3-8C03-0080C8D3C5D3}ProxyStubClsid]
@="{00020420-0000-0000-C000-000000000046}"
[HKEY_LOCAL_MACHINESOFTWAREClassesInterface{C8CF03E6-FD1F-11D3-8C03-0080C8D3C5D3}ProxyStubClsid32]
@="{00020420-0000-0000-C000-000000000046}"
[HKEY_LOCAL_MACHINESOFTWAREClassesInterface{C8CF03E6-FD1F-11D3-8C03-0080C8D3C5D3}TypeLib]
@="{C8CF03E5-FD1F-11D3-8C03-0080C8D3C5D3}"
"Version"="1.0"

没有我的客户没有运行的那些。从技术上讲,这只是所需的HKLM Software class Interface行。即使我不运行 regtlibv12.exe 并手动输入这4行,它也会开始运行。因此,有没有办法在不将这些行添加到注册表的情况下进行这项工作?

那么,有没有办法在不将这些行添加到注册表的情况下进行这项工作?

no,一个未经进程的服务器始终需要存在接口键。必不

用C 编写的COM服务器通常不是取决于类型的库申请,通常使用专用的代理/stub dll。它易于从IDL生成,MIDL工具自动生成DLL的源代码。您必须找到DLL并使用Regsvr32.exe将其注册并编写接口键。很少有面包屑可以让您找到DLL,除此之外,它会很小,也许在文件名中具有" PS"。

使用regtlibv12.exe或自己编写这些密钥是有效的解决方法。COM服务器曝光的接口实际上与类型库兼容。这是一个基于IDISPATCH的简单后期接口,严格使用自动化兼容类型,因此您不应该有任何问题。使用专用代理/存根的速度更快,但是当您使用缓慢的粘结量时,这已经不再重要了。

请小心依赖该服务器,它非常旧。如果有问题,您仍然不太可能获得支持。像这样。