【问题标题】:C++: Monitor process creation and termination in WindowsC++:在 Windows 中监视进程创建和终止
【发布时间】:2015-03-06 11:33:23
【问题描述】:

我碰巧看到了代码here的以下部分。

$Obj.ExecNotificationQueryAsync($hObj, "SELECT * FROM __InstanceCreationEvent WITHIN 0.5 WHERE TargetInstance ISA 'Win32_Process'")
$Obj.ExecNotificationQueryAsync($hObj, "SELECT * FROM __InstanceDeletionEvent WITHIN 0.5 WHERE TargetInstance ISA 'Win32_Process'")


Switch $OB.Path_.Class
            Case "__InstanceCreationEvent"
                ConsoleWrite("+~>" & _ProcessGetPath($OB.TargetInstance.ProcessID) & @CR)
            Case "__InstanceDeletionEvent"
                ConsoleWrite("!~>" & $OB.TargetInstance.ProcessID & @CR)
        EndSwitch

我使用相同的WQL 查询来监视C++ 中的进程。 C++ 中是否有类似的东西,通过它我可以知道它是创建还是终止进程。我尝试使用__CLASS,但它的输出为Win32_Process。我在MSVS2010 编码。

请帮忙。谢谢

编辑 1:添加 WQL 查询

hres = pSvc->ExecNotificationQueryAsync(
        _bstr_t("WQL"), 
        _bstr_t("SELECT * " 
            "FROM __InstanceDeletionEvent WITHIN 1 "
            "WHERE TargetInstance ISA 'Win32_Process' "), 
        WBEM_FLAG_SEND_STATUS, 
        NULL, 
        pStubSink);


     hres = pSvc->ExecNotificationQueryAsync(
        _bstr_t("WQL"), 
        _bstr_t("SELECT * " 
            "FROM __InstanceCreationEvent WITHIN 1 "
            "WHERE TargetInstance ISA 'Win32_Process'"), 
        WBEM_FLAG_SEND_STATUS, 
        NULL, 
        pStubSink);

使用上面的代码,我从 IWbemObjectSink::Indicate 方法获取进程的名称,无论是创建的还是终止的,打印到控制台中。

【问题讨论】:

  • 为每个查询设置单独的事件处理程序。如果 Creation 事件处理程序触发,则为创建,如果 Deletion 事件处理程序触发,则为终止
  • @stuartd:但是事件处理程序是否与事件发生时调用的ExecNotificationQueryAsync 函数(又调用Indicate 函数)有关?此外,我的句柄在 cpp 文件中定义,与包含函数定义的文件不同。

标签: c++ process wmi wmi-query wql


【解决方案1】:

为了使用单个 WQL 语句检测进程的创建和终止,您可以像这样使用 __InstanceOperationEvent 类。

Select * From __InstanceOperationEvent Within 1 Where TargetInstance ISA  Win32_Process

然后,如果您想确定到达事件的类型(类),您必须评估 __Class 属性。

试试这个示例

HRESULT EventSink::Indicate(long lObjectCount,
                            IWbemClassObject **apObjArray)
{
    HRESULT hr = S_OK;
    _variant_t vtProp;

    for (int i = 0; i < lObjectCount; i++)
    {
        bool CreateorDel = false;
        _variant_t cn;
        hr = apObjArray[i]->Get(_bstr_t(L"__Class"), 0, &cn, 0, 0);
        if (SUCCEEDED(hr))
        {
            wstring LClassStr(cn.bstrVal);
            if (0 == LClassStr.compare(L"__InstanceDeletionEvent") )
            {
                wcout << "Deletion" << endl;
                CreateorDel = true;
            }
            else if (0 == LClassStr.compare(L"__InstanceCreationEvent"))
            {
                wcout << "Creation" << endl;
                CreateorDel = true;
            }
            else
            {
                CreateorDel = false;
                //wcout << "Modification " << endl;             
            }
        }
        VariantClear(&cn);  

        if (CreateorDel)
        {
            hr = apObjArray[i]->Get(_bstr_t(L"TargetInstance"), 0, &vtProp, 0, 0);
            if (!FAILED(hr))
            {
                IUnknown* str = vtProp;
                hr = str->QueryInterface( IID_IWbemClassObject, reinterpret_cast< void** >( &apObjArray[i] ) );
                if ( SUCCEEDED( hr ) )
                {
                    _variant_t cn;
                    hr = apObjArray[i]->Get( L"Name", 0, &cn, NULL, NULL );
                    if ( SUCCEEDED( hr ) )
                    {

                        if ((cn.vt==VT_NULL) || (cn.vt==VT_EMPTY))
                            wcout << "Name : " << ((cn.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
                        else
                            wcout << "Name : " << cn.bstrVal << endl;
                    }
                    VariantClear(&cn);              

                    hr = apObjArray[i]->Get( L"Handle", 0, &cn, NULL, NULL );
                    if ( SUCCEEDED( hr ) )
                    {
                        if ((cn.vt==VT_NULL) || (cn.vt==VT_EMPTY))
                            wcout << "Handle : " << ((cn.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
                        else
                            wcout << "Handle : " << cn.bstrVal << endl;
                    }
                    VariantClear(&cn);
                }
            }
            VariantClear(&vtProp);
        }

    }

    return WBEM_S_NO_ERROR;
}

【讨论】:

  • 那太棒了.. 它奏效了。我的代码也有问题。我在您尝试过NameHandle 的地方尝试了__Class。非常感谢..
  • 我使用Select * From __InstanceOperationEvent Within 1 Where TargetInstance ISA 'Win32_Process'而不是Select * From __InstanceOperationEvent Within 1 Where TargetInstance ISA Win32_Process来消除错误。
  • 感谢代码 sn-p,这正是我想要的。我发现了一个小漏洞,当 QueryInterface 成功时,应该在 apObjArray[i] 上调用 Release。
猜你喜欢
  • 2015-10-18
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 2010-10-14
  • 2011-07-10
相关资源
最近更新 更多