从未通过 C# 注册C++ COM 服务器访问 COM 接口
Accessing COM Interface from C++ COM Server that doesn't register via C#
我被要求与已经发货的产品集成,该产品是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.0 win32]
@="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的简单后期接口,严格使用自动化兼容类型,因此您不应该有任何问题。使用专用代理/存根的速度更快,但是当您使用缓慢的粘结量时,这已经不再重要了。
请小心依赖该服务器,它非常旧。如果有问题,您仍然不太可能获得支持。像这样。
- 由非托管(C++)COM服务器实例化的托管(C#)控件在Windows更新后损坏
- 如何从客户端为COM服务器设置dll搜索路径?
- C# COM 服务器互操作 - System.InvalidCastException.
- 如何调试 Excel 对 COM 服务器的加载?
- COM 客户端连接 COM 服务器所需的文件是什么(进程外方案)
- 与同时32和64位客户端同时使用Process COM服务器
- 从未通过 C# 注册C++ COM 服务器访问 COM 接口
- 耗尽流程com服务器 - 每个呼叫过程一个服务器进程
- 从注册表中删除 COM 服务器的铭文会将键保留在 HKEY_CLASSES_ROOTTypeLib 中
- Reg Free进程外COM服务器事件
- OOP COM 服务器更新客户端
- 如何使用C++加载用 C# 编写的 COM 服务器
- C++ COM 服务器内存使用量随着时间的推移而增加 - 使用 WinDBG 的分析
- 以特定用户身份运行proc com服务器
- 验证进程外的COM服务器客户端是否受信任
- 如何获取调用COM服务器方法的用户的SID
- 如何获取调用COM服务器方法的用户名
- 在C#中为windows API编写COM服务器,从何开始
- ActiveQt Com应用程序示例- Com服务器未在Windows注册表中注册(Qt4.7.4)
- 检测谁启动了COM服务器