From: "H.Yamamoto" Date: 2004-06-16T21:34:13+09:00 Subject: [ruby-dev:23696] Re: Shell.Application on WIN32OLE 山本です。 Yuuji Oguri wrote: (2004/06/16 21:14) >MSDN には OleInitiailze() は内部的に COINIT_APARTMENTTHREADED を >引数として CoInitializeEx() を呼び出すとの記述があるので、 >multi thread がらみではないかと思います。 >Ruby の native thread 対応については把握してないので、 >これ以上はわかりませんが。 C++ のコードでも再現するので、ruby とは関係ないです。(bcc32でコンパイル) 謎なことに、shell->NameSpace で取得するフォルダがコントロールパネルのような仮想フォルダだと 落ちないんですよね。フロッピーとか、ハードディスクとか、物理フォルダだと落ちます。 #include #include #include void print(BSTR bstr) { char buf[10 * 1000]; // hack! hack! int n = WideCharToMultiByte( CP_ACP, 0, bstr, SysStringLen(bstr), buf, sizeof(buf) - 1, 0, 0); buf[n] = '\0'; puts(buf); } int main() { HRESULT hr; VARIANT v; BSTR bstr; IShellDispatch* shell; Folder* folder; Folder2* folder2; FolderItem* item; FolderItemVerbs* verbs; FolderItemVerb* verb; CoInitialize(0); hr = CoCreateInstance( CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&shell ); if (FAILED(hr)) puts("[error] CoCreateInstance"); v.vt = VT_I4; v.lVal = 2; hr = shell->NameSpace(v, &folder); if (FAILED(hr)) puts("[error] NameSpace"); hr = folder->QueryInterface(IID_Folder2, (void **)&folder2); if (FAILED(hr)) puts("[error] QueryInterface"); hr = folder2->get_Self(&item); if (FAILED(hr)) puts("[error] get_Self"); item->get_Name(&bstr); print(bstr); SysFreeString(bstr); hr = item->Verbs(&verbs); if (FAILED(hr)) puts("[error] Verbs"); v.vt = VT_I4; v.lVal = 0; hr = verbs->Item(v, &verb); if (FAILED(hr)) puts("[error] Item"); verb->get_Name(&bstr); print(bstr); SysFreeString(bstr); verb->Release(); CoFreeUnusedLibraries(); verbs->Release(); item->Release(); folder2->Release(); folder->Release(); shell->Release(); CoUninitialize(); return 0; }