/* 探秘com久已。 究其原理,至今仍迷糊。 看其应用,和脚本类似。 与其裹足不前,不如且行且研。 世上有几人明了,明了的人万事皆空,啥都不做了。 且看我这一把糊涂文吧! 以下示例修改自msdn。 除去了error的判断部分。 加了自己的注视,不当之处,敬请指导。 叹!微软操作系统结构的庞大,智能,垃圾! */ #include <iostream> using namespace std; #include <comdef.h> //_bstr_t类定义在这里。 #include <Wbemidl.h> //CLSID_WbemLocator 和 IID_IWbemLocator定义在这里。 #pragma comment(lib, "wbemuuid.lib") //CLSID_WbemLocator 和 IID_IWbemLocator定义在这里。 int main(int argc, char **argv) { CoInitializeEx(0, 0); CoInitializeSecurity(0, -1,0,0, 0, 3, 0, 0, 0 );//这一行可有可无。 IWbemLocator * pLoc = 0;//此类只有一个方法,不算继承。 CoCreateInstance( CLSID_WbemLocator, 0, 1, IID_IWbemLocator, (LPVOID *) & pLoc);//获得上面的类。 IWbemServices * pSvc = 0;//此类有20中方法。 pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), 0, 0, 0, 0, 0, 0, & pSvc);//连接并获得上面的类。 CoSetProxyBlanket(pSvc, 10, 0, 0, 3, 3, 0, 0 );//这一行可有可无。 IEnumWbemClassObject * pEnumerator = 0;//此类有5种办法,不算继承。 pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_Process"), 32 | 16, 0, & pEnumerator);//执行查询并获得上面的类。 while (pEnumerator) { IWbemClassObject * pclsObj;//此类有20多种办法。 ULONG uReturn = 0; pEnumerator->Next(-1, 1, & pclsObj, &uReturn);//移动指针,并获得上面的类。 if(0 == uReturn) break; VARIANT vtProp;//一个结构。 pclsObj->Get(L"Name", 0, &vtProp, 0, 0);//获得信息。 wcout << "Process Name : " << vtProp.bstrVal << endl; VariantClear(&vtProp);//清空结构。 } pSvc->Release(); pLoc->Release(); CoUninitialize(); return 0; } //made at 2011.12.21 //把以上代码改写成汇编的版本,我相信网上已经有了,我想也不是难事。 //下面的汇编代码摘抄自网络 .586 .model flat,stdcall option casemap:none include windows.inc include kernel32.inc include ole32.inc includelib kernel32.lib includelib ole32.lib .data CLSID_SpVoice GUID <096749377h, 03391h, 011D2h, <09Eh, 0E3h, 000h, 0C0h, 04Fh, 079h, 073h, 096h>> IID_ISpVoice GUID <06C44DF74h, 072B9h, 04992h, <0A1h, 0ECh, 0EFh, 099h, 06Eh, 004h, 022h, 0D4h>> TEXT db 'I',0,' ',0 ,'L',0 ,'o',0 ,'v',0 ,'e',0 ,' ',0 ,'Y',0 ,'o',0 ,'u',0 ,'!',0,0 .data? PCOM dd ? .code start: invoke CoInitialize,0 invoke CoCreateInstance,offset CLSID_SpVoice, 0, CLSCTX_INPROC_SERVER, offset IID_ISpVoice,offset PCOM .if eax == 0 push 0 push 0 push offset TEXT mov eax,PCOM push eax mov eax,[eax] call DWORD PTR[eax+50h] ;PCOM->Speak(L"I LOVE YOU!", 0, 0); .endif invoke ExitProcess,eax end start ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //一下2013.06.19日增加,摘自下面: //http://msdn.microsoft.com/en-us/library/ms720163(v=vs.85).aspx #include <stdafx.h> #include <sapi.h> int main(int argc, char* argv[]) { ISpVoice * pVoice = NULL; if (FAILED(::CoInitialize(NULL))) return FALSE; //注意下面一行多一个分号,去掉即可以编译通过. HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice;); if( SUCCEEDED( hr ) ) { hr = pVoice->Speak(L"Hello world", 0, NULL);//还可以用中文播放,是用SetVoice或者xml. pVoice->Release(); pVoice = NULL; } ::CoUninitialize(); return TRUE; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <stdafx.h> #include <sapi.h> #include <sphelper.h> int main(int argc, char* argv[]) { ISpVoice * pVoice = NULL; if (FAILED(::CoInitialize(NULL))) return FALSE; HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); if( SUCCEEDED( hr ) ) { //播放中文的方法一: ISpObjectToken * pSpObjectToken = NULL; SpFindBestToken(SPCAT_VOICES, L"language=804",NULL, &pSpObjectToken); hr = pVoice->SetVoice(pSpObjectToken); hr = pVoice->Speak(L"世界你好!", 0, NULL); //播放中文的方法二: pVoice->Speak(L"<lang langid=\"804\">世界你好!</lang>", SPF_DEFAULT, NULL); //播放英文,用默认的吧? hr = pVoice->Speak(L"Hello world", 0, NULL); //还有声音的大小,快慢,暂停等功能. pVoice->Release(); pVoice = NULL; } ::CoUninitialize(); return TRUE; }
2012年7月5日星期四
CoInitializeEx.Cpp
订阅:
博文评论 (Atom)
没有评论:
发表评论