2012年7月5日星期四

CoInitializeEx.Cpp

/*
探秘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;
}

没有评论:

发表评论