最近在搞進程外組件通訊的東西,寫了個demo,免註冊的,一直沒調通,其實就是兩個問題卡了好幾天,也沒找到有用的資料,試了好幾天終於才解決,現簡單記錄下來,省得你們跟我走同樣的彎路。下面com端程序名稱簡寫爲com.exe
遇到的問題:ui
1. 調用 CoGetClassObject, 返回hr = 0x80040154 沒有註冊類 (原回:註冊版的未註冊,免註冊版的未運行)
2. IClassFactory::CreateInstance(),返回hr = 0x80029c4a 加載類型庫/DLL 時出錯。(兩個exe不在同一目錄或與manifest中指定的路徑不一致)spa
1、實現步驟:
1.須要添加*.exe.manifest文件, Add進工程,Build.
注: manifest中填寫的com端exe路徑必須是com.exe 的真實存放路徑(默認在同級目錄下),可設置相對路徑(如Other\\ComExeDemo.exe),可嵌入到exe,沒必要放在exe同級目錄。
manifest文件例:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="Other\\com.exe" hashalg="SHA1">
<typelib tlbid="{F8311364-981D-4237-A33E-6738DCD1457B}" version="1.0" helpdir="" flags="HASDISKIMAGE"></typelib>
</file>
<comInterfaceExternalProxyStub name="IMyEvent" iid="{871965EB-D4BC-4131-9F97-2714105F9E76}" tlbid="{F8311364-981D-4237-A33E-6738DCD1457B}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
</assembly>debug
2. #import "*.tlb" ,目錄隨意,沒必要放在exe同級目錄。xml
3.客戶端與com端必須以相同權限運行。如:同爲管理員權限或同爲通常權限,不然失敗。可在調用端使用CreatProcess(Other\\ComExeDemo.exe)保證是統一權限。接口
4.客戶端獲取com端接口前必須保證com.exe 在運行狀態,這個運行的com.exe必須是manifest文件中指定路下的(通常與調用端exe放在同級),且與調用端權限統一。
客戶端獲取接口代碼例 :
進程
2、相關代碼ci
//初始化
AfxOleInit();
或::CoInitialize(NULL);
//啓動com端進程(權限統一哦)
//非必須-----------------------------------------
STARTUPINFO si;
PROCESS_INFORMATION pi;
::ZeroMemory( &si,sizeof(STARTUPINFO) );
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
BOOL b = ::CreateProcess(_T("E:\\CodeExercise\\vs2005\\COMDemo1Client\\debug\\11\\ComExeDemo.exe"),NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
//非必須-----------------------------------------
//獲取接口
CComPtr<IClassFactory> pFactory;
HRESULT hr = CoGetClassObject(CLSID_MyEvent, CLSCTX_LOCAL_SERVER, NULL, __uuidof(pFactory), reinterpret_cast<void**>(&pFactory));
IMyEventPtr pResult ;
hr = pFactory->CreateInstance(NULL, __uuidof(IMyEvent), reinterpret_cast<void**>(&pResult));hash
其實註冊版和免註冊版的區別就是一個用註冊表,一個用manifest代替註冊表,註冊版的在build時在註冊表裏寫死了com.exe的絕對路徑(可修改rgs文件使其不註冊),但免註冊版就得注意在編寫manifest文件時保證com.exe的路徑問題了。權限問題兩種版本都同樣,得統一!it