21

名前と PID を含む、Windows システム上のすべてのプロセスのリストを取得する必要があります。
EnumProcessは pid のリストを取得できますが、pid からプロセス名を取得するにはどうすればよいですか? 常に機能するとは限らないため、プロセスで OpenProcess を呼び出したくありません(他のプロセスが別のユーザーによって実行されている場合など)。

4

3 に答える 3

18

現在実行中のプロセスのexe名(あなたが書いたようなプロセス名)を受け取るために使用できる別のオプションがあります。最良の方法は、使用するプログラミング言語やその他の要件によって少し異なります。たとえば、WMI を使用できます。もう 1 つの古い方法は、パフォーマンス カウンターの使用です(パフォーマンス カウンターの紹介も参照してください)。HKEY_PERFORMANCE_DATAカウンター値を取得するには、ベース キーからレジストリ クエリ操作を使用するだけです(「カウンター データの取得」を参照) 。

もう 1 つの有効な方法は、パラメータとしてNtQuerySystemInformation関数を使用SystemProcessInformationすることです。EnumProcessおよび他の多くの Windows API は、関数を内部的に使用します。NtQuerySystemInformationSYSTEM_PROCESS_INFORMATIONのドキュメントで定義されている構造体には、多くの「ドキュメント化されていない」ものがありますが、長年にわたってよく知られているフィールドです。構造の定義をインターネットで検索すると、完全なドキュメントが表示されます。関数ハットのステータスが完全に文書化されていないのだろうか。この機能は、少なくとも NT 3.5 (おそらくそれ以前) にあり、現在は Windows 7 32 ビットまたは 64 ビットで適切に使用できます。正確には、すべてのプロセス ID を対応する exe 名 (完全な exe パスではなく、ファイル名のみ) と共に出力する小さな C テスト プログラムがあります。

#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;
}
于 2010-11-05T22:48:15.207 に答える
17

ToolHelp APInameを使用して、実行中のすべてのプロセスのプロセス ID を取得できます。 次のコードは、各プロセスのandを表示します。
pidname

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);
    }
}
于 2011-12-03T18:03:38.413 に答える
5

CreateToolhelp32Snapshot() はプロセス名を提供します (パスは提供しません)。それ以外は、OpenProcess() を呼び出す必要があります。コードが管理コンテキストで実行されている場合は、SE_DEBUG_NAME 権限を有効にして、他のコンテキストで実行されているプロセスにアクセスできます。

于 2010-11-05T11:33:00.497 に答える