Tôi hiện đang sử dụng chức năng EnumProcesses để lấy danh sách các quy trình đang chạy. Vì ứng dụng của tôi chạy trong không gian người dùng, tuy nhiên, nó không thể nhận được các xử lý cho các tiến trình không chạy dưới người dùng, bao gồm các tiến trình Hệ thống. Có phương pháp nào khác sẽ cho tôi quyền truy cập vào các phương pháp này không? Tất cả những gì tôi cần là tên quy trình.Nhận danh sách quy trình đang chạy đầy đủ (Visual C++)
Trả lời
Cuối cùng tôi đã tìm thấy một giải pháp (con số sau khi đăng bài ở đây là nỗ lực tuyệt vọng cuối cùng của tôi). Nếu bất kỳ ai khác chỉ cần một danh sách các tên quy trình đang chạy trên hệ thống (tất cả các quy trình), điều này sẽ làm điều đó cho bạn.
Truy vấn WMI (hoàn toàn có thể sử dụng giao diện COM của WMI, nhưng bạn cần dịch tài liệu tập trung VB (Tập lệnh)) có thể trợ giúp tại đây. Lớp học Win32_Process
chứa những gì bạn cần.
Tuy nhiên, tôi chưa thử nghiệm điều này, tôi nghĩ bạn sẽ tìm thấy cùng một vấn đề: người không phải quản trị viên chỉ có thể xem quy trình của riêng họ.
Chỉ cần để thêm vào câu trả lời này, tôi đã xây dựng này đối với trường hợp khi bạn đang tìm kiếm chỉ là một quá trình cụ thể thay vì toàn bộ danh sách.
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;
}
tôi nên lưu ý ở đây điều này đã được viết bằng Embarcadero RAD Studio (C++ Builder) và mỗi hệ thống @Remy_Lebeau :: AnsiString là một chuỗi lớp C++ Builder cho dữ liệu nhân vật 8bit ANSI trong khuôn khổ VCL/FMX của nó.
Nếu tất cả bạn cần chỉ là cái tên quá trình, sau đó sử dụng WTSEnumerateProcesses như vậy:
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;
}
Lợi ích của việc sử dụng phương pháp này là bạn không cần phải mở mỗi quá trình cá nhân và sau đó lấy tên của nó như bạn sẽ phải làm gì nếu bạn đã thay đổi bằng cách sử dụng EnumProcesses, điều này cũng sẽ không hoạt động nếu bạn cố gắng mở các quy trình chạy với đặc quyền cao hơn tài khoản người dùng của bạn.
Ngoài ra, phương pháp này cũng nhanh hơn nhiều so với gọi số Process32First()
/Process32Next()
trong vòng lặp.
WTSEnumerateProcesses
là một API ít được biết đến đã có sẵn từ Windows XP.
Bạn có thể quan tâm đến điều này: http://stackoverflow.com/q/30604485/560648. –
Cảm ơn, tôi nên lưu ý ở đây này được viết trong Embarcadero RAD Studio (C++ Builder) và mỗi @Remy_Lebeau System :: AnsiString là lớp chuỗi C++ Builder cho dữ liệu ký tự 8 bit ANSI trong khung công tác VCL/FMX của nó. – Phil
Chắc chắn giá trị thêm chi tiết đó vào câu trả lời của bạn! Chúc mừng. –