/*
探秘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)
没有评论:
发表评论