获取当前用户的所有流程

时间:2014-05-30 23:35:35

标签: c++ winapi c++11 wmi win32-process

我需要为当前用户获取所有进程。目前我有一个使用WMI实现的功能,它可以获取所有用户的所有活动进程。我需要以某种方式获得当前用户的所有流程。

如果您转到Windows的“任务管理器”,“详细信息”选项卡,您将看到所有用户的所有进程。但是说你在Visual Studio中,然后进入Debug / Attach To Process,这将显示当前用户的所有进程。这就是我需要的清单。

以下是我对所有用户的所有流程的解决方案:

    CComPtr<IEnumWbemClassObject> pEnumerator;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_Process"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

WMI或Win32解决方案都足够好。谢谢!!

1 个答案:

答案 0 :(得分:2)

好的,现在有短路。但是,如果有人有兴趣,这是工作解决方案:

std::wstring GetProcessUserName(DWORD dwProcessId)
{
    HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
    if (processHandle != NULL)
    {
        HANDLE tokenHandle;
        if (OpenProcessToken(processHandle, TOKEN_READ, &tokenHandle))
        {
            TOKEN_USER tokenUser;
            ZeroMemory(&tokenUser, sizeof(TOKEN_USER));
            DWORD tokenUserLength = 0;

            PTOKEN_USER pTokenUser;
            GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS::TokenUser, NULL,      
            0, &tokenUserLength);
            pTokenUser = (PTOKEN_USER) new BYTE[tokenUserLength];

            if (GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS::TokenUser, pTokenUser, tokenUserLength, &tokenUserLength))
            {
                TCHAR szUserName[_MAX_PATH];
                DWORD dwUserNameLength = _MAX_PATH;
                TCHAR szDomainName[_MAX_PATH];
                DWORD dwDomainNameLength = _MAX_PATH;
                SID_NAME_USE sidNameUse;
                LookupAccountSid(NULL, pTokenUser->User.Sid, szUserName, &dwUserNameLength, szDomainName, &dwDomainNameLength, &sidNameUse);
                delete pTokenUser;
                return std::wstring(szUserName);
            }
        }
    }

    return std::wstring();
}

std::unordered_map<std::wstring, std::vector<DWORD>> GetAllRunningProcessesForCurrentUser()
{
    std::unordered_map<std::wstring, std::vector<DWORD>> processHash;

    HRESULT hres;

    // Initialize COM. ------------------------------------------

    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres))
    {
        return processHash;
    }

    do {
        // Obtain the initial locator to WMI -------------------------

        CComPtr<IWbemLocator> pLoc;
        hres = pLoc.CoCreateInstance(CLSID_WbemLocator);
        if (FAILED(hres))
        {
            break;
        }

        // Connect to WMI through the IWbemLocator::ConnectServer method
        // Connect to the root\cimv2 namespace with
        // the current user and obtain pointer pSvc
        // to make IWbemServices calls.
        CComPtr<IWbemServices> pSvc;
        hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
        NULL,                    // User name. NULL = current user
        NULL,                    // User password. NULL = current
        0,                       // Locale. NULL indicates current
        NULL,                    // Security flags.
        0,                       // Authority (for example, Kerberos)
        0,                       // Context object 
        &pSvc                    // pointer to IWbemServices proxy
        );

        if (FAILED(hres))
        {
            break;
        }

        // Set security levels on the proxy -------------------------
        hres = CoSetProxyBlanket(
        pSvc,                        // Indicates the proxy to set
        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
        NULL,                        // Server principal name 
        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        NULL,                        // client identity
        EOAC_NONE                    // proxy capabilities 
        );

        if (FAILED(hres))
        {
            break;
        }

        // Use the IWbemServices pointer to make requests of WMI ----

        CComPtr<IEnumWbemClassObject> pEnumerator;
        hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_Process"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

        if (FAILED(hres))
        {
            break;
        }

        // Get the data from the query in step 6 -------------------

        CComPtr<IWbemClassObject> pclsObj;
        while (pEnumerator)
        {
            ULONG uReturn = 0;
            HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

            if (0 == uReturn)
            {
                break;
            }

            VARIANT vtProp;
            VARIANT vtProp2;

            hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
            hr = pclsObj->Get(L"ProcessId", 0, &vtProp2, NULL, NULL);

            auto userName = GetProcessUserName(vtProp2.intVal);

            TCHAR szActiveUserName[_MAX_PATH];
            DWORD dwActiveUserNameLength = _MAX_PATH;
            GetUserName(szActiveUserName, &dwActiveUserNameLength);

            if (_tcscmp(userName.c_str(), szActiveUserName) == 0)
            {
                processHash[vtProp.bstrVal].push_back(vtProp2.intVal);
            }


            VariantClear(&vtProp2);
            VariantClear(&vtProp);

            pclsObj.Release();
        }
    } while (false);

    CoUninitialize();

    return processHash;
}