获取完整的运行进程列表(Visual C++)

发布于 2024-09-14 17:13:29 字数 124 浏览 7 评论 0原文

我目前正在使用 EnumProcesses 函数来获取正在运行的进程的列表。然而,由于我的应用程序在用户空间中运行,因此它无法获取不在用户下运行的进程(包括系统进程)的句柄。是否有其他方法可以让我访问这些内容?我所需要的只是进程名称。

I am currently using the EnumProcesses function to obtain a list of running processes. Since my application runs in user space, however, it is not able to get handles for processes not running under the user, including System processes. Is there another method that will give me access to these? All I need are the process names.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

方圜几里 2024-09-21 17:13:29

只是为了补充这个答案,我为您只查找一个特定进程而不是整个列表的情况构建了这个。

bool FindRunningProcess(AnsiString process) {
/*
Function takes in a string value for the process it is looking for like ST3Monitor.exe
then loops through all of the processes that are currently running on windows.
If the process is found it is running, therefore the function returns true.
*/
    AnsiString compare;
    bool procRunning = false;

    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hProcessSnap == INVALID_HANDLE_VALUE) {
        procRunning = false;
    } else {
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(hProcessSnap, &pe32)) { // Gets first running process
            if (pe32.szExeFile == process) {
                procRunning = true;
            } else {
                // loop through all running processes looking for process
                while (Process32Next(hProcessSnap, &pe32)) { 
                    // Set to an AnsiString instead of Char[] to make compare easier
                    compare = pe32.szExeFile;
                    if (compare == process) {
                        // if found process is running, set to true and break from loop
                        procRunning = true;
                        break;
                    }
                }
            }
            // clean the snapshot object
            CloseHandle(hProcessSnap);
        }
    }

    return procRunning;
}

我应该注意到,这是在 Embarcadero RAD Studio (C++ Builder) 中编写的,并且根据 @Remy_Lebeau System::AnsiString 是一个 C++Builder 字符串类,用于其 VCL/FMX 框架中的 8 位 ANSI 字符数据。

Just to add to this answer, I built this for cases when you are looking for just one particular process instead of the entire list.

bool FindRunningProcess(AnsiString process) {
/*
Function takes in a string value for the process it is looking for like ST3Monitor.exe
then loops through all of the processes that are currently running on windows.
If the process is found it is running, therefore the function returns true.
*/
    AnsiString compare;
    bool procRunning = false;

    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hProcessSnap == INVALID_HANDLE_VALUE) {
        procRunning = false;
    } else {
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(hProcessSnap, &pe32)) { // Gets first running process
            if (pe32.szExeFile == process) {
                procRunning = true;
            } else {
                // loop through all running processes looking for process
                while (Process32Next(hProcessSnap, &pe32)) { 
                    // Set to an AnsiString instead of Char[] to make compare easier
                    compare = pe32.szExeFile;
                    if (compare == process) {
                        // if found process is running, set to true and break from loop
                        procRunning = true;
                        break;
                    }
                }
            }
            // clean the snapshot object
            CloseHandle(hProcessSnap);
        }
    }

    return procRunning;
}

I should note here this was written in Embarcadero RAD Studio (C++ Builder) and per @Remy_Lebeau System::AnsiString is a C++Builder string class for 8bit ANSI character data in its VCL/FMX frameworks.

水染的天色ゝ 2024-09-21 17:13:29

我终于找到了一个解决方案(在此处发布作为我最后一次绝望尝试后的数字)。如果其他人只需要系统上运行的进程名称列表(所有进程),这将为您完成。

进程行走

I finally found a solution (figures after posting here as my last desperate attempt). If anyone else only needs a list of process names running on the system (all processes), this will do it for you.

Process Walking

你的笑 2024-09-21 17:13:29

如果您只需要进程名称,请使用 WTSEnumerateProcesses 因此:

WTS_PROCESS_INFO* pWPIs = NULL;
DWORD dwProcCount = 0;
if(WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, NULL, 1, &pWPIs, &dwProcCount))
{
    //Go through all processes retrieved
    for(DWORD i = 0; i < dwProcCount; i++)
    {
        //pWPIs[i].pProcessName = process file name only, no path!
        //pWPIs[i].ProcessId = process ID
        //pWPIs[i].SessionId = session ID, if you need to limit it to the logged in user processes
        //pWPIs[i].pUserSid = user SID that started the process
    }
}

//Free memory
if(pWPIs)
{
    WTSFreeMemory(pWPIs);
    pWPIs = NULL;
}

使用此方法的好处是,您不必单独打开每个进程,然后检索其名称,就像使用 EnumProcesses 相反,如果您尝试,这也不起作用打开以比您的用户帐户更高的权限运行的进程。

此外,此方法也比循环调用 Process32First()/Process32Next() 快得多。

WTSEnumerateProcesses 是一个鲜为人知的 API,自 Windows XP 起就可用。

If all you need are just process names, then use WTSEnumerateProcesses as such:

WTS_PROCESS_INFO* pWPIs = NULL;
DWORD dwProcCount = 0;
if(WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, NULL, 1, &pWPIs, &dwProcCount))
{
    //Go through all processes retrieved
    for(DWORD i = 0; i < dwProcCount; i++)
    {
        //pWPIs[i].pProcessName = process file name only, no path!
        //pWPIs[i].ProcessId = process ID
        //pWPIs[i].SessionId = session ID, if you need to limit it to the logged in user processes
        //pWPIs[i].pUserSid = user SID that started the process
    }
}

//Free memory
if(pWPIs)
{
    WTSFreeMemory(pWPIs);
    pWPIs = NULL;
}

The benefit of using this method is that you don't have to open each process individually and then retrieve its name as what you'd have to do if you went with EnumProcesses instead, which also won't work if you try to open processes that run with higher privileges than your user account.

Additionally this method is also much faster than calling Process32First()/Process32Next() in a loop.

WTSEnumerateProcesses is a lesser known API that has been available since Windows XP.

锦爱 2024-09-21 17:13:29

WMI 查询(很可能使用 WMI 的 COM 接口,但您需要翻译 VB(脚本)重点文档)可能会有所帮助。 Win32_Process类包含您需要的内容。

但是,我没有对此进行测试,我想您会发现同样的问题:非管理员只能看到自己的进程。

A WMI query (quite possible using WMI's COM interface, but you'll need to translate VB(Script) focused documentation) might help here. The Win32_Process class contains what you need.

However, I've not tested this, I think you'll find the same issue: a non-administrator can only see their own processes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文