开发者

get process name from process id (win32)

I need to get a list of all processes on a windows system including names and PID.

EnumProcess can obtain a list of pids, but how do I get the process name from the p开发者_如何学JAVAid? I don't want to call OpenProcess on the process as that doesn't always work (like if the other process is run by a different user).


You have different option which you can use to receive exe names of currently running processes (process names like you wrote). The best way depends a little from the programming language which you use and from other requirements. For example you can use WMI. One other more old way is the usage of Performance Counters (see also An Introduction To Performance Counters). To get the counters values you can just use registry query operations from the HKEY_PERFORMANCE_DATA base key (see Retrieving Counter Data)

One more way which can be also good used is the NtQuerySystemInformation function with SystemProcessInformation as a parameter. EnumProcess and many other Windows API use the function internally. The struct SYSTEM_PROCESS_INFORMATION defined in the documentation of NtQuerySystemInformation has many "undocumented" but since many many years well-known fields. If you search in the Internet for the definition of the structure you will fined full documentation. I wonder that the function hat status not full documented. The function was at least in NT 3.5 (probably also before) and can be good used now on Windows 7 32- or 64-bit. To be exact below you will find a small C test program which print all process ids with the corresponding exe names (not full exe path, just the file name):

#include <Windows.h>
// one can also use Winternl.h if needed
//#include <Winternl.h> // for UNICODE_STRING and SYSTEM_INFORMATION_CLASS
#include <stdio.h>
#include <tchar.h>

#define STATUS_SUCCESS               ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH  ((NTSTATUS)0xC0000004L)

typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemProcessInformation = 5
} SYSTEM_INFORMATION_CLASS;

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;

typedef LONG KPRIORITY; // Thread priority

typedef struct _SYSTEM_PROCESS_INFORMATION_DETAILD {
    ULONG NextEntryOffset;
    ULONG NumberOfThreads;
    LARGE_INTEGER SpareLi1;
    LARGE_INTEGER SpareLi2;
    LARGE_INTEGER SpareLi3;
    LARGE_INTEGER CreateTime;
    LARGE_INTEGER UserTime;
    LARGE_INTEGER KernelTime;
    UNICODE_STRING ImageName;
    KPRIORITY BasePriority;
    HANDLE UniqueProcessId;
    ULONG InheritedFromUniqueProcessId;
    ULONG HandleCount;
    BYTE Reserved4[4];
    PVOID Reserved5[11];
    SIZE_T PeakPagefileUsage;
    SIZE_T PrivatePageCount;
    LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION_DETAILD, *PSYSTEM_PROCESS_INFORMATION_DETAILD;

typedef NTSTATUS (WINAPI *PFN_NT_QUERY_SYSTEM_INFORMATION)(
  IN       SYSTEM_INFORMATION_CLASS SystemInformationClass,
  IN OUT   PVOID SystemInformation,
  IN       ULONG SystemInformationLength,
  OUT OPTIONAL  PULONG ReturnLength
);

int main()
{
    size_t bufferSize = 102400;
    PSYSTEM_PROCESS_INFORMATION_DETAILD pspid=
        (PSYSTEM_PROCESS_INFORMATION_DETAILD) malloc (bufferSize);
    ULONG ReturnLength;
    PFN_NT_QUERY_SYSTEM_INFORMATION pfnNtQuerySystemInformation = (PFN_NT_QUERY_SYSTEM_INFORMATION)
        GetProcAddress (GetModuleHandle(TEXT("ntdll.dll")), "NtQuerySystemInformation");
    NTSTATUS status;

    while (TRUE) {
        status = pfnNtQuerySystemInformation (SystemProcessInformation, (PVOID)pspid,
                                              bufferSize, &ReturnLength);
        if (status == STATUS_SUCCESS)
            break;
        else if (status != STATUS_INFO_LENGTH_MISMATCH) { // 0xC0000004L
            _tprintf (TEXT("ERROR 0x%X\n"), status);
            return 1;   // error
        }

        bufferSize *= 2;
        pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD) realloc ((PVOID)pspid, bufferSize);
    }

    for (;;
         pspid=(PSYSTEM_PROCESS_INFORMATION_DETAILD)(pspid->NextEntryOffset + (PBYTE)pspid)) {

        _tprintf (TEXT("ProcessId: %d, ImageFileName: %ls\n"), pspid->UniqueProcessId,
            (pspid->ImageName.Length && pspid->ImageName.Buffer)? pspid->ImageName.Buffer: L"");

        if (pspid->NextEntryOffset == 0) break;
    }

    return 0;
}


Ýou can get the process identifier and name for all running processes using the ToolHelp API.
The following code will display the pid and name for each process.

void showProcessInformation() {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if(hSnapshot) {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if(Process32First(hSnapshot, &pe32)) {
            do {
               printf("pid %d %s\n", pe32.th32ProcessID, pe32.szExeFile);
            } while(Process32Next(hSnapshot, &pe32));
         }
         CloseHandle(hSnapshot);
    }
}


CreateToolhelp32Snapshot() will give you the process name (but not the path); other than that, you will have to call OpenProcess(). If your code is running in an administrative context you could enable the SE_DEBUG_NAME privilege to get access to processes running under other contexts.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜