I'm creating a windows program that basically scans the system to see if a particular process is running or not. I have the process name (AcroRd32.exe) and nothing else.
From what I've read the easiest way to create a snapshot of all processes using CreateToolhelp32Snapshot and then iterate through each process looking for the process name.
My application is highly performance centric. So is there a better more efficient way to do this.
The application collects a snapshot every few seconds. Iterating through 100's of processes in the snapshot doesn't seem efficient. Is there a direct API that can find the Process through its process name (and retrieve process handle or id through the name)?
I've searched extensively without much luck. Has anyone tried this before?
The fastest way to scan for processes is via NTDLL's NtQuerySystemInformation call. It provides you with a list of names and process IDs of all processes on the system with a single call (or more in rare cases, i.e. large # of processes). You can combine NtQuerySystemInformation and use a hash to do string comparisons instead of comparing each byte.
// headers # http://pastebin.com/HWzJYpbv
NtQuerySystemInformation = (_RT_NAPI_QUERYSYSINFO)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQuerySystemInformation");
// Get process information buffer
do {
// Allocate buffer for process info
pBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cbBuffer);
if (pBuffer == NULL) {
// Cannot allocate enough memory for buffer (CRITICAL ERROR)
return 1;
}
// Obtain system process snapshot
Status = NtQuerySystemInformation(5, pBuffer, cbBuffer, NULL);
// Allocate bigger buffer for moar data
if (Status == STATUS_INFO_LENGTH_MISMATCH) {
HeapFree(hHeap, 0, pBuffer);
cbBuffer *= 2; // Increase the size of the buffer :-)
} else if ((Status) != 0x00) {
// Can't query process information (probably rootkit or anti-virus)
HeapFree(hHeap, 0, pBuffer);
return 1;
}
} while (Status == STATUS_INFO_LENGTH_MISMATCH);
// Get pointer to first system process info structure
pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
// Loop over each process
for (;;) {
// Get process name
pszProcessName = pInfo->ImageName.Buffer;
// ... do work. For a fast string compare, calculate a 32-bit hash of the string, then compare to a static hash.
if(CRC32(pszProcessName) == 0xDEADBEEF /* <- hash of adobe reader process name goez here */) {
// Found process
}
// Load next entry
if (pInfo->NextEntryOffset == 0)
break;
pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo)+ pInfo->NextEntryOffset);
}
Tested on Windows 2000 - Windows 7 English editions, x64/x86 (except Win XP x64)
Note: It will return all processes to 32-bit WOW64 processes on 64-bit systems.
No.
Each process has a unique ID but not unique name. There could be multiple processes with the same name. So it is impossible to get the process handle out of its name directly without iterating over all processes.
Internally all prcesses are linked together somehow, e.g., in a linked list. Even if there was a function GetProcessByName() provided, it would internally traverse the list to find those processes with that name on behalf of you as well. So that won't make a big difference in performance.
Aside
Give a shot to EnumProcesses() which has less overhead and is simpler. Check here.
BOOL WINAPI EnumProcesses(
__out DWORD *pProcessIds,
__in DWORD cb,
__out DWORD *pBytesReturned
);
MSDN has an example for this.
Related
For the purposes of performance monitoring on Windows OS, I need a program which can report both user and kernel times for an arbitrary process. On POSIX systems, standard time utility is perfectly OK as it reports wall clock time, user time and kernel time.
For Windows, there is no such utility by default. I looked around and found at least three alternatives. As I explain below, none of them actually suits my needs.
timeit from Windows SDK (cannot recall what exact version). It is no longer distributed, supported, or guaranteed to work on modern systems. I was not able to test it.
Cygwin's time. Almost identical to POSIX counterpart with similar output formatting.
timep.exe by Johnson (John) Hart, available in source code and binaries for his book "Windows System Programming, 4th Edition". This is a pretty simple utility that uses WinAPI's GetProcessTimes() to obtain the very same three values. I suspect that Cygwin's time is no different in that regard.
Now the problem: GetProcessTimes() only reports times for the PID directly spawned by timep, but not its children. This makes both time and timep useless for me.
My target EXE application is typically spawned through a BAT file which invokes one more BAT file; both BATs are meant to tune environment or alter command line arguments:
timep.exe
|
+---wrapper.bat
|
+--- real-wrapper.bat
|
+--- application.exe
Times reported for wrapper.bat alone tell nothing about application.exe.
Obviously, process creation models of POSIX (fork-exec) and Win32 (CreateProcess) are very different, which makes my goal that hard to achieve on Windows.
I want to try to write my own variant of time. It has to sum up times for given process and all his children, grandchildren etc., recursively. So far I can imagine the following approach:
CreateProcess() and get its PID (root PID) and handle; add this handle to a list
Enumerate all processes in system; for each process
Compare its PID with root PID. If equal, get PID and handle for it, add it to the handle list.
For every new PID, repeat process scan phase to collect more children handles
Recurse down until no new process handles are added to the list
Wait for all collected handles from the list to terminate.
For each handle, call GetProcessTimes() and sum them up
Report results
This algorithm is bad because it is racy — children processes may be created late in the life of any process, or they can terminate before we get a chance to obtain their handle. In both cases, reported result times will be incorrect.
My question is: Is there a better solution?
EDIT: I was able to achieve my goal by using Job Objects. Below is a code snippet extracted from my application, relevant to obtaining kernel and user times from a process and all of its children. Hopefully it will save some time for someone.
I tested it with Windows 8.1 x64 and VS 2015, but it should be backwards-portable to at least Windows 7. Some fiddling might be required for 32-bit hosts (I am not sure) in regard to long long types - I am not familiar with CL.EXE's ways of dealing with them on such platforms.
#include <windows.h>
#include <string>
#include <cassert>
#include <iostream>
/* ... */
STARTUPINFO startUp;
PROCESS_INFORMATION procInfo;
/* Start program in paused state */
PROCESS_INFORMATION procInfo;
if (!CreateProcess(NULL, CmdParams, NULL, NULL, TRUE,
CREATE_SUSPENDED | NORMAL_PRIORITY_CLASS, NULL, NULL, &startUp, &procInfo)) {
DWORD err = GetLastError();
// TODO format error message
std::cerr << "Unable to start the process: " << err << std::endl;
return 1;
}
HANDLE hProc = procInfo.hProcess;
/* Create job object and attach the process to it */
HANDLE hJob = CreateJobObject(NULL, NULL); // XXX no security attributes passed
assert(hJob != NULL);
int ret = AssignProcessToJobObject(hJob, hProc);
assert(ret);
/* Now run the process and allow it to spawn children */
ResumeThread(procInfo.hThread);
/* Block until the process terminates */
if (WaitForSingleObject(hProc, INFINITE) != WAIT_OBJECT_0) {
DWORD err = GetLastError();
// TODO format error message
std::cerr << "Failed waiting for process termination: " << err << std::endl;
return 1;
}
DWORD exitcode = 0;
ret = GetExitCodeProcess(hProc, &exitcode);
assert(ret);
/* Calculate wallclock time in nanoseconds.
Ignore user and kernel times (third and fourth return parameters) */
FILETIME createTime, exitTime, unusedTime;
ret = GetProcessTimes(hProc, &createTime, &exitTime, &unusedTime, &unusedTime);
assert(ret);
LONGLONG createTimeNs = (LONGLONG)createTime.dwHighDateTime << 32 | createTime.dwLowDateTime;
LONGLONG exitTimeNs = (LONGLONG)exitTime.dwHighDateTime << 32 | exitTime.dwLowDateTime;
LONGLONG wallclockTimeNs = exitTimeNs - createTimeNs;
/* Get total user and kernel times for all processes of the job object */
JOBOBJECT_BASIC_ACCOUNTING_INFORMATION jobInfo;
ret = QueryInformationJobObject(hJob, JobObjectBasicAccountingInformation,
&jobInfo, sizeof(jobInfo), NULL);
assert(ret);
if (jobInfo.ActiveProcesses != 0) {
std::cerr << "Warning: there are still "
<< jobInfo.ActiveProcesses
<< " alive children processes" << std::endl;
/* We may kill survived processes, if desired */
TerminateJobObject(hJob, 127);
}
/* Get kernel and user times in nanoseconds */
LONGLONG kernelTimeNs = jobInfo.TotalKernelTime.QuadPart;
LONGLONG userTimeNs = jobInfo.TotalUserTime.QuadPart;
/* Clean up a bit */
CloseHandle(hProc);
CloseHandle(hJob);
Yes, from timep.exe create a job, and use job accounting. Child processes (unless created in their own jobs) share the job with their parent process.
This pretty much skips your steps 2-4
I've packaged the solution for this problem into a standalone program for Windows called chronos. It creates a job object and then spawns a requested process inside it. All the children spawned later stay in the same job object and thus can be accounted later.
I need to know how many instances of my process are running on a local Windows system. I need to be able to do it using C++/MFC/WinAPIs. So what is a reliable method to do this?
I was thinking to use process IDs for that, stored as a list in a shared memory array that can be accessed by the process. But the question is, when a process is closed or crashes how soon will its process ID be reused?
The process and thread identifiers may be reused any time after closure of all handles. See When does a process ID become available for reuse? for more information on this.
However if you are going to store a pair of { identifier, process start time } you can resolve these ambiguities and detect identifier reuse. You can create a named file mapping to share information between the processes, and use IPC to synchronize access to this shared data.
You can snag the process handles by the name of the process using the method described in this question. It's called Process Walking. That'll be more reliable than process id's or file paths.
A variation of this answer is what you're looking for. Just loop through the processes with Process32Next, and look for processes with the same name using MatchProcessName. Unlike the example in the link I provided, you'll be looking to count or create a list of the processes with the same name, but that's a trivial addition.
If you are trying to limit the number of instances of your process to some number you can use a Semaphore.
You can read in detail here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686946(v=vs.85).aspx
In a nutshell, the semaphore is initialized with a current count and max count. Each instance of your process will decrement the count when it acquires the semaphore. When the nth process tries to acquire it but the count has reached zero that process will fail to acquire it and can terminate or take appropriate action.
The following code should give you the gist of what you have to do:
#include <windows.h>
#include <stdio.h>
// maximum number of instances of your process
#define MAX_INSTANCES 10
// name shared by all your processes. See http://msdn.microsoft.com/en-us/library/windows/desktop/aa382954(v=vs.85).aspx
#define SEMAPHORE_NAME "Global\MyProcess"
// access rights for semaphore, see http://msdn.microsoft.com/en-us/library/windows/desktop/ms686670(v=vs.85).aspx
#define MY_SEMAPHORE_ACCESS SEMAPHORE_ALL_ACCESS
DWORD WINAPI ThreadProc( LPVOID );
int main( void )
{
HANDLE semaphore;
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
semaphore = CreateSemaphore(
NULL, // default security attributes
MAX_INSTANCES, // initial count
MAX_INSTANCES, // maximum count
SEMAPHORE_NAME );
if (semaphore == NULL)
{
semaphore = OpenSemaphore(
MY_SEMAPHORE_ACCESS,
FALSE, // don't inherit the handle for child processes
SEMAPHORE_NAME );
if (semaphore == NULL)
{
printf("Error creating/opening semaphore: %d\n", GetLastError());
return 1;
}
}
// acquire semaphore and decrement count
DWORD acquireResult = 0;
acquireResult = WaitForSingleObject(
semaphore,
0L); // timeout after 0 seconds trying to acquire
if(acquireResult == WAIT_TIMEOUT)
{
printf("Too many processes have the semaphore. Exiting.");
CloseHandle(semaphore);
return 1;
}
// do your application's business here
// now that you're done release the semaphore
LONG prevCount = 0;
BOOL releaseResult = ReleaseSemaphore(
semaphore,
1, // increment count by 1
&prevCount );
if(!releaseResult)
{
printf("Error releasing semaphore");
CloseHandle(semaphore);
return 1;
}
printf("Semaphore released, prev count is %d", prevCount);
CloseHandle(semaphore);
return 0;
}
Well, your solution is not very reliable. PIDs can be reused by the OS at any later time.
I did it once by going through all the processes and comparing their command line string (the path of the executable) with the one for my process. Works pretty well.
Extra care should be taken for programs that are started via batch files (like some java apps/servers).
Other solutions involve IPC, maybe through named pipes, sockets, shared memory (as you mentioned). But none of them are that easy to implement and maintain.
is there a way for a forked child to examine another forked child so that, if the other forked child takes more time than usual to perform its chores, the first child may perform predefined steps?
if so, sample code will be greatly appreciated.
Yes. Simply fork the process to be watched, from the process to watch it.
if (fork() == 0) {
// we are the watcher
pid_t watchee_pid = fork();
if (watchee_pid != 0) {
// wait and/or handle timeout
int status;
waitpid(watchee_pid, &status, WNOHANG);
} else {
// we're being watched. do stuff
}
} else {
// original process
}
To emphasise: There are 3 processes. The original, the watcher process (that handles timeout etc.) and the actual watched process.
To do this, you'll need to use some form of IPC, and named shared memory segments makes perfect sense here. Your first child could read a value in a named segment which the other child will set once it has completed it's work. Your first child could set a time out and once that time out expires, check for the value - if the value is not set, then do what you need to do.
The code can vary greatly depending on C or C++, you need to select which. If C++, you can use boost::interprocess for this - which has lots of examples of shared memory usage. If C, then you'll have to put this together using native calls for your OS - again this should be fairly straightforward - start at shmget()
This is some orientative code that could help you to solve the problem in a Linux environment.
pid_t pid = fork();
if (pid == -1) {
printf("fork: %s", strerror(errno));
exit(1);
} else if (pid > 0) {
/* parent process */
int i = 0;
int secs = 60; /* 60 secs for the process to finish */
while(1) {
/* check if process with pid exists */
if (exist(pid) && i > secs) {
/* do something accordingly */
}
sleep(1);
i++;
}
} else {
/* child process */
/* child logic here */
exit(0);
}
... those 60 seconds are not very strict. you could better use a timer if you want more strict timing measurement. But if your system doesn't need critical real time processing should be just fine like this.
exist(pid) refers to a function that you should have code that looks into proc/pid where pid is the process id of the child process.
Optionally, you can implement the function exist(pid) using other libraries designed to extract information from the /proc directory like procps
The only processes you can wait on are your own direct child processes - not siblings, not your parent, not grandchildren, etc. Depending on your program's needs, Matt's solution may work for you. If not, here are some other alternatives:
Forget about waiting and use another form of IPC. For robustness, it needs to be something where unexpected termination of the process you're waiting on results in your receiving an event. The best one I can think of is opening a pipe which both processes share, and giving the writing end of the pipe to the process you want to wait for (make sure no other processes keep the writing end open!). When the process holding the writing end terminates, it will be closed, and the reading end will then indicate EOF (read will block on it until the writing end is closed, then return a zero-length read).
Forget about IPC and use threads. One advantage of threads is that the atomicity of a "process" is preserved. It's impossible for individual threads to be killed or otherwise terminate outside of the control of your program, so you don't have to worry about race conditions with process ids and shared resource allocation in the system-global namespace (IPC objects, filenames, sockets, etc.). All synchronization primitives exist purely within your process's address space.
I am working on a program to sort data, and I need to to set the process to priority 31, which I believe is the highest process priority in Windows. I have done some research, but can't figure out how to do it in C++.
The Windows API call SetPriorityClass allows you to change your process priority, see the example in the MSDN documentation, and use REALTIME_PRIORITY_CLASS to set the highest priority:
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)
Caution: if you are asking for true realtime priority, you are going to get it. This is a nuke. The OS will mercilessly prioritize a realtime priority thread, well above even OS-level input processing, disk-cache flushing, and other high-priority time-critical tasks. You can easily lock up your entire system if your realtime thread(s) drain your CPU capacity. Be cautious when doing this, and unless absolutely necessary, consider using high-priority instead. More information
The following function will do the job:
void SetProcessPriority(LPWSTR ProcessName, int Priority)
{
PROCESSENTRY32 proc32;
HANDLE hSnap;
if (hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
if (hSnap == INVALID_HANDLE_VALUE)
{
}
else
{
proc32.dwSize = sizeof(PROCESSENTRY32);
while ((Process32Next(hSnap, &proc32)) == TRUE)
{
if (_wcsicmp(proc32.szExeFile, ProcessName) == 0)
{
HANDLE h = OpenProcess(PROCESS_SET_INFORMATION, TRUE, proc32.th32ProcessID);
SetPriorityClass(h, Priority);
CloseHandle(h);
}
}
CloseHandle(hSnap);
}
}
For example, to set the priority of the current process to below normal, use:
SetProcessPriority(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS)
After (or before) SetPriorityClass, you must set the individual thread priority to achieve the maximum possible. Additionally, another security token is required for realtime priority class, so be sure to grab it (if accessible). SetThreadPriority is the secondary API after SetPriorityClass.
How can I create a global counter-value that can be shared between multiple processes in c++? What I need is a way to "invalidate" multiple processes at once, signaling them to perform some operation (like reading from file). All processes would continuously poll (every 10ms) for current counter-value and compare it with internally stored last value. Mismatching values would indicate that some work is needed.
Edit: btw my processes are executing as different .exe:s, not created from some parent process. Operating system is windows.
What about a named semaphore? Posix supports it, not sure about windows.
Consider the way you want to distribute the information and potential overlaps - if it takes longer for any of the readers to finish reading than it takes for a refresh then you are going to get in trouble with the suggested approach.
The way I read your question, there are multiple readers, the writer doesn't know (or care in most part) how many readers there are at one time, but wants to notify the readers that something new is available to read.
Without knowing how many potential readers there are you can't use a simple mutex or semaphore to know when the readers are done, without knowing when everybody is done you don't have good info on when to reset an event to notify for the next read event.
MS Windows specific:
Shared Segments
One option is to place variables within a shared data segment. That means that the same variables can be read (and written to) by all exe's that have named the same segment or if you put it into a DLL - loaded the shared DLL.
See http://www.codeproject.com/KB/DLL/data_seg_share.aspx for more info.
// Note: Be very wary of using anything other than primitive types here!
#pragma data_seg(".mysegmentname")
HWND hWnd = NULL;
LONG nVersion = -1;
#pragma data_seg()
#pragma comment(linker, "/section:.mysegmentname,rws")
IPC - COM
Make your main app a com service where the workers can register with for events, push out the change to each event sink.
IPC - dual events
Assuming any 1 read cycle is much less than time between write events.
create 2 manual reset events, at any time at most 1 of those events will be signaled, alternate between events. signaling will immediatly release all the readers and once complete they will wait on the alternate event.
you can do this the easy way or the way
the easy way is to store shared values in registry or a file so that all processes agree to check it frequently.
the hard way is to use IPC(inter process communication, the most common method that i use is NamedPipes. its not too hard because you can find plenty of resources about IPC on the net.
If you are on *nix you could make the processes read from a named pipe (or sockets), and then write the specific msg there to tell the other processes that they should shutdown.
IPC performance: Named Pipe vs Socket
Windows NAmed Pipes alternative in Linux
Use a named event object with manual reset. The following solution doesn't use the CPU so much than busy waiting
Sending process:
Set event
Sleep 10 ms
Reset Event
Receiving processes:
All waiting processes pass when event is set
They read the file
Let them sleep for 20 ms, so say can't see the same event twice.
Wait again
Sleep( 10 ) might actually take longer than Sleep( 20 ) but this only results in another cycle (reading the unchanged file again).
As the name of the executable is known, I have another solution which I implemented (in C#) in a project just a few days ago:
Every reader process creates a named event "Global\someuniquestring_%u" with %u being it's process id. If the event is signaled, read the file and do the work.
The sender process has a list of event handles and sets them active if the file has changed and thus notifys all reader processes. From time to time, e.g. when the file has changed, it has to update the list of event handles:
Get all processes with name 'reader.exe' (e.g.)
For every process get it's id
Open a handle for the existing event "Global\someuniquestring_%u" if it's a new process.
Close all handles for no longer running processes.
Found one solution for monitoring folder changes (with "event_trigger"-event) and reading additional event information from file:
HANDLE event_trigger;
__int64 event_last_time;
vector<string> event_info_args;
string event_info_file = "event_info.ini";
// On init
event_trigger = FindFirstChangeNotification(".", false, FILE_NOTIFY_CHANGE_LAST_WRITE);
event_last_time = stat_mtime_force("event_info.ini");
// On tick
if (WaitForSingleObject(event_trigger, 0)==0)
{
ResetEventTrigger(event_trigger);
if (stat_mtime_changed("event_info.ini", event_last_time))
{
FILE* file = fopen_force("event_info.ini");
char buf[4096];
assert(fgets(buf, sizeof(buf), file));
split(buf, event_info_args, "\t\r\n");
fclose(file);
// Process event_info_args here...
HWND wnd = ...;
InvalidateRect(wnd,0,false);
}
}
// On event invokation
FILE* file = fopen("event_info.ini", "wt");
assert(file);
fprintf(file,"%s\t%s\t%d\n",
"par1", "par2", 1234);
fclose(file);
stat_mtime_changed("event_info.ini", event_last_time);
// Helper functions:
void ResetEventTrigger()
{
do
{
FindNextChangeNotification(evt);
}
while(WaitForSingleObject(evt, 0)==0);
}
FILE* fopen_force(const char* file);
{
FILE* f = fopen(file, "rt");
while(!f)
{
Sleep(10+(rand()%100));
f = fopen(f, "rt");
}
assert(f);
return f;
}
__int64 stat_mtime_force(const char* file)
{
struct stat stats;
int res = stat(file, &stats);
if(res!=0)
{
FILE* f = fopen(file, "wt");
fclose(f);
res = stat(file, &stats);
}
assert(res==0);
return stats.st_mtime;
}
bool stat_mtime_changed(const char* file, __int64& time);
{
__int64 newTime = stat_mtime(file);
if (newTime - time > 0)
{
time = newTime;
return true;
}
return false;
}