EternalWindows
COM基礎 / アウトプロセスサーバー

前節では、インプロセスサーバーとして実装されているオブジェクトを作成しましたが、 あるオブジェクトがインプロセスかアウトプロセスかはどのように見極めればよいのでしょうか。 実は、レジストリのHKEY_CLASSES_ROOT\CLSID以下には、オブジェクトのCLSIDの名前を持ったキーが作成されており、 その下に作成されているサブキーの名前から実装形態を特定することができます。 次の図は、前節で取り上げたCLSID_FileOpenDialog({DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7})をregedt32.exeで確認したものです。

結論から述べると、InProcServer32というサブキーがあればサーバーはインプロセスです。 その証拠に、既定のエントリにはオブジェクトを実装するDLLのパスが格納されています。

さて、それではアウトプロセスサーバーの場合は、どのようなサブキーが作成されているのでしょうか。 例として、CLSID_InternetExplorer({0002DF01-0000-0000-C000-000000000046})を確認します。

LocalServer32というサブキーが作成されていれば、サーバーはアウトプロセスになります。 この場合は、既定のエントリにオブジェクトを実装するEXEのパスが格納されることになります。

今回のプログラムは、CLSID_InternetExplorerで表されるオブジェクトをCoCreateInstanceで作成します。 先に示した図からも分かるように、オブジェクトの正体はInternetExplorerであり、 これがプロセスとして起動されることになります。 CLSID_InternetExplorerを参照する場合は、exdisp.hのインクルードが必要になります。

#include <windows.h>
#include <exdisp.h>

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
	HRESULT      hr;
	IWebBrowser2 *pWebBrowser2;
	BSTR         bstrUrl;
	VARIANT      varFlags, varTargetFrameName, varPostData, varHeaders;

	CoInitialize(NULL);

	hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pWebBrowser2));
	if (FAILED(hr)) {
		CoUninitialize();
		return 0;
	}

	pWebBrowser2->put_Visible(VARIANT_TRUE);
	
	bstrUrl = SysAllocString(L"http://www.yahoo.co.jp/");
	VariantInit(&varFlags);
	VariantInit(&varTargetFrameName);
	VariantInit(&varPostData);
	VariantInit(&varHeaders);
	pWebBrowser2->Navigate(bstrUrl, &varFlags, &varTargetFrameName, &varPostData, &varHeaders);

	SysFreeString(bstrUrl);
	pWebBrowser2->Release();
	CoUninitialize();
	
	return 0;
}

CLSID_InternetExplorerで識別されるオブジェクトはアウトプロセスサーバーでしたから、 これを作成する場合は3引数にCLSCTX_LOCAL_SERVERを指定します。 このオブジェクトはIWebBrowser2を実装しているため、 オブジェクトを受け取る変数の型はIWebBrowser2になっています。 関数が成功した場合はInternetExplorerのプロセスが作成されますが、 こうした形で作成されたアウトプロセスサーバーは基本的にウインドウを表示しません。 よって、表示するためのメソッドであるput_Visibleを呼び出すことになります。

Navigateを呼び出した場合、InternetExplorerは第1引数のURLにアクセスします。 文字列はBSTR型でなければならないため、UNICODE文字列をBSTR型に変換するSysAllocStringを呼び出すことになります。 残りの引数については、初期化済みのVARIANT構造体を指定すれば問題ありません。


戻る