I am going to open game process from my trainer app and write some values to memory. I have no problems with opening a process and writing a value to memory. But I can't realize how to monitor the game process availability. For example I opened a running process, user closed it and opened again. How can I track this in my code? OpenProcess handle is valid even after the process is closed (until CloseHandle called). Thank you.
You can use the GetExitCodeProcess function to see if the handle you have points to a running process.
DWORD exitCode=0;
::GetExitCodeProcess(hProcess, &exitCode);
if (exitCode==STILL_ACTIVE)
; //process is alive
MSDN link
Or else, if it's more suitable for your application to have the process termination event signalled to you (process is a waitable object):
::WaitForSingleObject(hProcess, dwTimeout);
Related
the Program entry point function is WinMain
and it doesn't create a Window so it runs in the background.
I want to get a notification when the program is closed like: by the user through task manager or through system shutdown so I can save some progress.
something like the windows messages WM_QUITE but I can't access that as far as I know cuz i don't create a window
If there is no window, you may consider modifying the program registration as a DLL service plug-in.
The service also has no window and executes in the background.
The process is closed. Only the kernel callback knows that a process is killed. There will be no event whether the R3 process is closed.
Unless you have another process intermittently scanning the process list continuously.
Registering as a service at least you can receive event callbacks when your service is stopped by others.
CreateServiceW
https://learn.microsoft.com/zh-cn/windows/win32/services/installing-a-service
Is the background program something that your own code started, using CreateProcess()? If so, you can use the process handle (hProcess in the PROCESS_INFORMATION structure) in functions like WaitForSingleObject() etc. to check if the process still runs.
I had a process with C++ on windows 2008R2, there are several theads in it. During the process's startup, there is a chance that one of the thread will exit. I didn't get a way to detect what happens, any suggestions?
Based on my investigation, the thread just exit without an exception. Access to a null pointer can cause the similar issue, but I didn't find such a position in the process. In fact, it should be better if the process just crash, then I can get a dump file; but nothing happens, just one thread exit.
I had tried the tool user mode process dumper, but it cannot work on the windows version that this process is working on.
I had tried the tool process monitor to check the thread exit event, but the process monitor will throw an exception when I try to reproduce this issue by starting the process again and again.
Thanks in advance.
Found the root cause at last -- the string is accessed by more than one threads, and one thread just exit. String is not thread safe.
Process Monitor helped to get the thread exit call stack on a powerful host, this makes the root cause clear.
Thanks all for your suggestions.
I have a program (runs as a background process) in which I installed a hook to capture EVENT_SYSTEM_FOREGROUND events (i.e - when the user switches between windows). The callback which is registered for the hook basically logs what application (process exe filename) the user has switched from and which they have switched to.
I want to add some code to check if the application they have switched from is still active (if not we assume they have closed it and that is what has brought a new window into the foreground). I am testing for it's existence by trying to create a handle to the previous PID using OpenProcess
//Check prev pid still exists - if not, assume the previous app has been closed
HANDLE hPrevProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,false,g_prevPid);
if (hPrevProc==NULL){
prevProcStillRunning=false;
}
else{
CloseHandle(hPrevProc);
}
Assumptions with the code above:
g_prevPid is populated with a PID - I have verified this
prevProcStillRunning has been initialized to true
The problem with the code above is that for some reason, even when the user has exited an app (say notepad.exe for example). For up to 10 seconds after they have exited, this test still passes (i.e - hPrevProc gets initialised). Even though I can see in the task manager that the Notepad.exe process has dissapeared (and yes I only have one instance of it opened), somehow, the OpenProcess line still can get a handle on that PID. I am guessing that somehow the PID actually still exists but it may be in a state where its terminating. I have found that if this code is called a few more times, eventually it will return null.
I would like to find out a better way I can test whether hPrevProc is still acitive.
I tried to test this using the GetExitCodeProcess function but this seems to just give me the PID and I'm not even sure if that's the right approach in any case.
Any help appreciated.
The process subsists in the system after it terminates at least while there is an open handle to it.
The only foolproof method to know whether a process is still active is:
make sure the process cannot exit with code STILL_ACTIVE (259)
try to open the process (OpenProcess)-> if you cannot is is terminated
read the exit process code (GetExitCodeProcess) -> if it is not STILL_ACTIVE the process is terminated.
You code could become:
//Check prev pid still exists - if not, assume the previous app has been closed
HANDLE hPrevProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,false,g_prevPid);
if (hPrevProc==NULL){
prevProcStillRunning=false;
}
else{
DWORD cr;
if ((GetExitCodeProcess(hPrevProc, &cr) == 0) || (cr != STILL_ACTIVE)) {
prevProcStillRunning=false;
}
CloseHandle(hPrevProc);
}
Anyway, closing a GUI application involves different steps:
the GUI elements are destroyed
the message loop ends
eventually the application could do background operations (save state to file, etc.)
the main procedure returns an exit code
the system knows that the application is terminated
The event will be sent as soon as the main window will be closed, which can happen some time before the application actually stops. A good example for that is Firefox. If you close the window and immediately try to start a new process, you will get an error because even if the UI is gone, the process is not still terminated. What is worse, is that you can find applications that simply go into background when you close the UI, and allow user to open UI again through an action on an icon in the status area of the taskbar (Shell_NotifyIcon and its callback). This is common for services of other application working in background (network servers, firewalls, etc.). In that case, the UI is gone but the process will not terminate.
TL/DR: the time between the disparition of the UI and the termination of the process owning it is variable and depends on the system load and the background activity of the process after closing the UI. You can try to use a delay for that but I cannon guarantee anything about it...
Probably some process (maybe yours?) still holds a valid handle to this process. Until CloseHandle was called on all handles, system maintains internal record which allow to access its process data. This is important because as you say it must be possible to call GetExitCodeProcess on closed process, also someone might want to wait for it to stop with WaitForSingleObject.
Also be carefull with PIDs, they can be reused - so in theory you might call OpenProcess on some other newly opened process.
As for checking if given process is not a zombie, you might try enumerating top level windows with EnumWindows, and checking if any of them is associated with given PID (to get window's PID use GetWindowThreadProcessID).
Is there a way to kill my app's child process and perform it's cleanup(calling deconstructors and atexit functions), similarly to exit(exit_code), but on another process?
If you are on windows, you probably start your child processes by CreateProcess, which has a PROCESS_INFORMATION as the last parameter.
CreateProcess on MSDN
Process Information on MSDN
Option 1:
This process information contains a handle to the process started in the hProcess member.
You can store this handle and use it to kill your child processes.
Insert
You probably want to send WM_CLOSE and / or WM_QUIT?
to "cleanly" end the process:
Here is a KB Article on what to do KB how to cleanly kill win32 processes
** End Insert**
Option 2:
Here is an discussion on how to properly kill a process tree: Terminate a process tree on windows
There's no simple Win32 API for that kind of thing. The OS doesn't care what language your program's source code was written in, the compiled program appears to it as just a sequence of CPU instructions plus data.
The cleanest way would be to establish some kind of a communication channel between the processes (e.g. via shared memory) and simply request process termination.
You can achieve the same by starting the child process as a debugged process and then using debug APIs to alter the child's behavior, but that's too intrusive and not very straightforward to implement.
I am invoking several processes in my main and I can get the pid of that processes. Now I want to wait until all this processes have been finished and then clear the shared memory block from my parent process. Also if any of the process not finished and segfaulted I want to kill that process. So how to check from the pid of processes in my parent process code that a process is finished without any error or it gave broke down becoz of runtime error or any other cause, so that I can kill that process.
Also what if I want to see the status of some other process which is not a child process but its pid is known.
Code is appreciated( I am not looking for script but code ).
Look into waitpid(2) with WNOHANG option. Check the "fate" of the process with macros in the manual page, especially WIFSIGNALED().
Also, segfaulted process is already dead (unless SIGSEGV is specifically handled by the process, which is usually not a good idea.)
From your updates, it looks like you also want to check on other processes, which are not children of your current process.
You can look at /proc/{pid}/status to get an overview of what a process is currently doing, its either going to be:
Running
Stopped
Sleeping
Disk (D) sleep (i/o bound, uninterruptable)
Zombie
However, once a process dies (fully, unless zombied) so does its entry in /proc. There's no way to tell if it exited successfully, segfaulted, caught a signal that could not be handled, or failed to handle a signal that could be handled. Not unless its parent logs that information somewhere.
It sounds like your writing a watchdog for other processes that you did not start, rather than keeping track of child processes.
If a program segfaults, you won't need to kill it. It's dead already.
Use the wait and waitpid calls to wait for children to finish and check the status for some idea of how they exiting. See here for details on how to use these functions. Note especially the WIFSIGNALED and WTERMSIG macros.
waitpid() from SIGCHLD handler to catch the moment when application terminates itself. Note that if you start multiple processes you have to loop on waitpid() with WNOHANG until it returns 0.
kill() with signal 0 to check whether the process is still running. IIRC zombies still qualify as processes thus you have to have proper SIGCHLD handler for that to work.