【问题标题】:Is there a way to list every windows processes from cpp?有没有办法从 cpp 列出每个 Windows 进程?
【发布时间】:2021-12-23 03:41:48
【问题描述】:

我最近希望列出机器的每个进程以执行某些操作。但是我正在努力处理不是从我的用户(例如:系统、管理员或其他用户)启动的进程。

我尝试了一些代码和一些解决方案,但仍然有任何可行的方法。

我正在编写微软提出的枚举所有进程的代码。

代码如下:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>

// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1

void PrintProcessNameAndID( DWORD processID )
{
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                   PROCESS_VM_READ,
                                   FALSE, processID );

    // Get the process name.

    if (NULL != hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), 
             &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName, 
                               sizeof(szProcessName)/sizeof(TCHAR) );
        }
    }

    // Print the process name and identifier.

    _tprintf( TEXT("%s  (PID: %u)\n"), szProcessName, processID );

    // Release the handle to the process.

    CloseHandle( hProcess );
}

int main( void )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
    {
        return 1;
    }


    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name and process identifier for each process.

    for ( i = 0; i < cProcesses; i++ )
    {
        if( aProcesses[i] != 0 )
        {
            PrintProcessNameAndID( aProcesses[i] );
        }
    }

    return 0;
}

此代码有效,但不允许您查看其他用户的进程。你有什么想法吗?

感谢大家的宝贵时间。 问候

【问题讨论】:

  • 如果您在提升模式下以管理员身份运行您的程序是否可以工作?
  • 你说的不允许你查看其他用户的进程是什么意思?您甚至没有获得他们的 processID,或者您只是无法获得他们的名字?
  • 您不太可能获得PROCESS_VM_READ 访问其他用户启动的进程的权限。如果您完成了基本的错误处理,您已经获得了这么多信息。
  • @SergeBallesta 从另一个用户运行的每个进程的名称将是“”。因此,如果我不知道 PID,我将无法获取进程名称。
  • @TedLyngmo 这不起作用,因为它只会捕获来自管理员用户的进程。

标签: c++ windows process


【解决方案1】:

作为普通用户,您不会通过在您不拥有的进程上使用OpenProcess 来取得成功。如果您提升您的进程并启用调试权限,您可能会有更多的运气。您可能仍会被拒绝访问 DRM 和 AntiVirus 进程。一般来说,PSAPI 函数期望对进程进行大量访问,PROCESS_VM_READ 是最大的问题,Windows 不会授予您对所有其他进程的内存读取访问权限。一些较新的 API,如 GetProcessImageFileName 已升级(在 Vista+ 中)只需要 PROCESS_QUERY_LIMITED_INFORMATION,您可能会获得更多进程。

我建议改用Toolhelp API,它应该比EnumProcesses+OpenProcess 提供更多信息。您还可以从性能计数器和 WMI 中获取一些信息。

作为旁注; EnumProcesses 是有史以来最没用的 API。它使用 NT API 获取有关所有进程的信息,然后丢弃除进程 ID 之外的所有信息。

如果您愿意使用未记录的内容,NT 查询/信息功能将比任何记录的 API 为您提供更多信息。

【讨论】:

    【解决方案2】:

    我认为最合理的解决方案是使用 CreateToolhelp32Snapshot 你可以在https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot进行一些查找

    这是一个小例子

    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        std::cout << "CreateToolhelp32Snapshot (of processes) failed with error " << GetLastError() << std::endl;
        return;
    
    pe32.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hProcessSnap, &pe32))
    {
        std::cout << "Failed getting first process" << std::endl;
        CloseHandle(hProcessSnap);          
        return;
    }
    do
    {
        std::cout << "Process: " << pe32.szExeFile << std::endl;
    } while (Process32Next(hProcessSnap, &pe32));
    CloseHandle(hProcessSnap);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多