我需要獲取Windows系統上所有進程的列表,包括名稱和PID。
EnumProcess可以獲得pid列表,但是如何從pid獲取進程名稱?我不想在流程上調用OpenProcess,因爲這並不總是有效(例如,如果另一個流程由不同的用戶運行)。從進程ID獲取進程名稱(win32)
回答
CreateToolhelp32Snapshot()會給你進程名稱(但不是路徑);除此之外,你將不得不打電話給OpenProcess()。如果您的代碼在管理環境中運行,則可以啓用SE_DEBUG_NAME特權來訪問在其他環境下運行的進程。
您有不同的選項,您可以使用它來接收當前正在運行的進程(進程名稱,如您所寫的)的exe名稱。最好的方式取決於您使用的編程語言和其他需求。例如,您可以使用WMI。另一種更老的方式是使用Performance Counters(另請參閱An Introduction To Performance Counters)。要獲取計數器值你可以使用註冊表查詢操作從HKEY_PERFORMANCE_DATA
基本密鑰(見Retrieving Counter Data)
另一種方式可以是還不錯採用的是NtQuerySystemInformation函數SystemProcessInformation
作爲參數。 EnumProcess
和許多其他Windows API在內部使用該函數。在NtQuerySystemInformation文檔中定義的結構SYSTEM_PROCESS_INFORMATION
有許多「無證」,但自許多年以來衆所周知的領域。如果你在互聯網上搜索結構的定義,你將被罰款完整的文件。我不知道功能帽狀態沒有完整記錄。該功能至少在NT 3.5(可能還在之前),現在可以很好地用於Windows 7 32位或64位。要確切下面你會發現一個小的C性能測試,其打印所有進程ID與相應的exe文件名(不完整的exe路徑,只是文件名):
#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;
}
,你可以得到的進程標識符和name
所有正在運行的進程使用ToolHelp API。
以下代碼將顯示每個進程的pid
和name
。
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);
}
}
您只需要使用: pe32.dwSize = sizeof(PROCESSENTRY32);在調用Process32First() – hB0 2012-02-13 13:59:20
@ hB0之前 - 錯過了那個=) – Cyclonecode 2012-02-13 16:01:06
這真的很酷,比'NtQuerySystemInformation'技術快得多。有沒有什麼方法可以通過這種技術獲得PID創建時間? – Noitidart 2016-01-10 13:03:10
- 1. 從進程名稱獲取進程ID
- 2. 如何從進程名稱獲取進程ID?
- 3. 從進程ID獲取進程可執行文件名稱
- 4. 獲取進程的ID從進程名稱
- 5. 通過名稱獲取進程ID
- 6. 從子進程獲取父進程ID
- 7. SharpPcap獲取進程名稱
- 8. 從進程ID /對象獲取進程實例名稱(更快的方法)
- 9. 從進程名稱獲取應用程序名稱
- 10. 如何從進程名稱獲取應用程序名稱?
- 11. 從CSCore獲取進程名稱或ID audiostream
- 12. 我如何從進程ID獲取服務的名稱?
- 13. Volume Mixer - 獲取應用程序名稱及其進程ID
- 14. 如何獲取所有線程ID和進程的名稱
- 15. Win32確定進程ID
- 16. 獲取PowerShell進程的進程ID
- 17. 如何在linux中通過進程名獲取進程ID
- 18. 獲取所有進程id進程名在linux
- 19. 啓動Win32進程A啓動進程B - 獲取B的ID/HWND
- 20. 通過PID獲取進程名稱
- 21. 獲取進程名稱,使用AppleScript
- 22. 通過圖像名稱獲取進程的進程句柄
- 23. 如何在QT中獲取加載進程的進程名稱
- 24. 按進程名稱獲取進程句柄
- 25. 如何獲取Win32線程的名稱?
- 26. shelljs - 獲取由shelljs.exec()創建的進程的進程ID()進程
- 27. 獲取Scala.sys.process.Process的進程ID
- 28. 正確獲取進程ID
- 29. 獲取子進程ID
- 30. 如何使用模塊獲取進程ID,名稱和狀態
我不認爲你可以在Vista之後的Windows版本上可靠地做到這一點。你正在使用哪個版本? – 2010-11-05 00:20:13
你可以使用WMI來做這個 – 2010-11-05 00:56:22
你是什麼意思的進程名稱--EXE名稱? – 2010-11-05 12:15:28