On my system there is an application (App.exe) that runs, but sometimes it terminates (gracefully and expectantly). At the same time I have another application that, when App.exe is stopped, needs to perform certain tasks. So I need a way to monitor App.exe from my application.
Something like the following is what I am trying to accomplish
If (App.exe is running wait 360 seconds for it to terminate)
if (App.exe is not running anymore)
do the work I need to do when App.exe is NOT running
So, they KEY is:
how do I evaluate if App.exe is running
how do I wait 360 seconds for it to close (if it is still running)
Now this is not very difficult if my Application is the onw that started/spwaned App.exe (using CreateProcess and WaitForExit stuff), but in this case I am not the controlling agent ... so how do I monitor to see if App.exe is still running and consequently wait (for period of time X) for it to end before doing something specific?
Any hints, help, or recommendantions would be much appreciated.
Thanks,
You can use the ToolHelp APIs (CreateToolhelp32Snapshot with TH32CS_SNAPPROCESS and Process32Next) to get the process id of any running app.exe processes. From that you can use OpenProcess to get a handle which you can then use wait on for termination.
How about a call to FindWindow to get the handle(or handles if the app can have multiple instances, or changes its title based on open documents), a call to GetWindowThreadProcessId and OpenProcess to convert it, then a call to WaitForSingleObject?
I believe you could use GetProcessesByName().
Related
I have some legacy code that launches Word (and other applications) from a C++ program using COM automation and the MSO dll. This runs on a server, non-interactively.
Occasionally the application will hang and eventually over many day/weeks, the resources on the server will be used up by many hung processes.
The process is launched:
Word::_ApplicationPtr wordApp
HRESULT hr = wordApp.CreateInstance(__uuidof(Word::Application));
various calls are then made via the wordApp pointer, one of which may hang. The code never returns form the call and the C++ code is stalled.
What is a solution to checking for these hangs and then killing off Word?
I have pondered using CreateProcess and using waitforsingleobject with a timeout but I cant then manipulate the object via automation.
I cant see a way of retrieving the handle to the COM launched app so cant kill it using that.
I thought about a separate thread and waiting on that then killing the thread after a timeout but killing a thread doesnt release all the resources i.e. word.
I thought about enumming all the active processes and searching for "winword" then killing every process that matched but this seems messy and a hack.
So anyone any ideas?
Thanks.
Is it possible to create a windows service to create and maintain another process? Like I'm writing a program, and say a virus killed the process, could I have my window service running and basically 'watching' it? I already have the code for a regular application that stays running and executes a program if it's not currently running, to keep it running.
I've never written a service before, but would it be that hard to just write this simple program, which basically runs a check to see if the process is running, if not, it executes it and sleeps for a few minutes?
Thanks.
Yes, it is possible. It is not uncommon to see third-party apps have watchdog services to keep them running in case of crashes. A service can enumerate running processes using EnumProcesses(), and if the desired executable is not running then start a new copy of it using CreateProcessAsUser().
If the service is the one starting the executable process in the first place, or can find it after an enumeration, one optimization would be to keep an open handle to the process (returned by CreateProcess...(), or use OpenProcess() on the process ID an enumeration returns), and then use a wait function, like WaitForSingleObject(), to detect when the process stops running. That way, you don't have to enumerate processes to find out if the intended process is still running or not.
Is there some way to detect that a program was ended by windows task manager's "end process"?
I know that its kinda impossible to do that from within the application being ended (other than to build your app as a driver and hook ZwTerminateProcess), but I wonder if there is a way to notice it from outside.
I don't want to stop the program from terminating, just to know that it was ended by "end process" (and not by any other way).
There might be a better way - but how about using a simple flag?
Naturally, you'd have to persist this flag somewhere outside of the process/program's memory - like the registry, database, or file system. Essentially, when the app starts up, you set the flag to 'True' when the app shuts down through the normal means, you set the flag to 'False'.
Each time the application starts you can check the flag to see if it was not shut down correctly the previous time it was executed.
Open up a handle to the process with OpenProcess, and then wait on that handle using one of the wait functions such as WaitForSingleObject. You can get the exit status of the process using GetExitCodeProcess. If you need your program to remain responsive to user input while waiting, then make sure to wait on a separate thread (or you can periodically poll using a timeout of zero, but remember the performance consequences of polling -- not recommended).
When you're done, don't forget to call CloseHandle. The process object won't be fully deleted from the OS until all of its handles are closed, so you'll leak resources if you forget to call CloseHandle.
Note that there's no way to distinguish between a process exiting normally or being terminated forcefully. Even if you have a convention that your program only ever exits with a status of 0 (success) or 1 (failure) normally, some other process could call TerminateProcess(YourProcess, 1), and that would be indistinguishable from your ordinary failure mode.
According to the documentation, ExitProcess calls the entry point of all loaded DLLs with DLL_PROCESS_DETACH, whereas TerminateProcess does not. (Exiting the main function results in a call to ExitProcess, as do most unhandled exceptions.)
You might also want to look into Application Recovery and Restart.
One option might be to create a "watchdog" application (installed as a service, perhaps) that monitors WMI events for stopping a process via the ManagementEventWatcher class (in the System.Management namespace).
You could query for the death of your process on an interval or come up with some event driven way to alert of your process's demise.
Here's sort of an example (it's in C# though) that could get you started.
Is it possible to have a program restart automatically if it crashes?
Something like:
An unhandled exception is thrown.
Release all resources allocated by process.
Start over and call main.
I would like this behavior for a server application I'm working on. If clients miss use the server it can get a std::bac_alloc exception, in which case I would like the server to simply restart instead of crashing and shutting down, thus avoiding manual startup.
I've done this before in Windows by running said program from another program via a win32 CreateProcess call. The other program then waits on the "monitored" process to exit, and calls its CreateProcess() again if it does. You wait for a process to exit by performing a WaitForSingleObject on the process' handle, which you get as one of the return values from your CreateProcess() call.
You will of course want to program in some way to make the monitoring process shut itself and its child process down.
Let Windows be your watchdog. You can call ChangeServiceConfig2 to set the failure actions for your service. (If your server isn't a service, then you're doing it wrong.) Specify SERVICE_CONFIG_FAILURE_ACTIONS for the dwInfoLevel parameter, and in the SERVICE_FAILURE_ACTIONS structure, set lpsaActions to an array of one or more SC_ACTION values. The type you want is SC_ACTION_RESTART.
I did something similar by implementing a watchdog. The watchdog ran as a service and would wait for a ping (called petting the dog) from the monitored process. If the monitored process died due to an exception, watchdog would cleanup and relaunch the application.
In case the application was not responding(no ping in a certain time) the watchdog would kill it and then restart it.
Here is a link to an implementation that you might want to use:
http://www.codeproject.com/KB/security/WatchDog.aspx
(PS: I implemented my own version but I cannot post it here. I found this from a quick google search and have no first hand experience with this particular implementation.)
If you just catch the exception, it should be possible to just restart your server by internal programming logic without completely restarting the whole program.
Like #T.E.D., we've done this in an application we built. Our application is a windows service, so the helper program stops the service (eventually kill it, if it hangs) and start the service again.
I need to execute some commands via "/bin/sh" from a daemon. Some times these commands takes too long to execute, and I need to somehow interrupt them. The daemon is written in C++, and the commands are executed with std::system(). I need the stack cleaned up so that destructors are called when the thread dies. (Catching the event in a C++ exception-handler would be perfect).
The threads are created using boost:thread. Unfortunately, neither boost::thread::interrupt() or pthread_cancel() are useful in this case.
I can imagine several ways to do this, from writing my own version of system(), to finding the child's process-id and signal() it. But there must be a simpler way?
Any command executed using the system command is executed in a new process. Unfortunately system halts the execution of the current process until the new process completes. If the sub process hangs the new process hangs as well.
The way to get round this is to use fork to create a new process and call one of the exec calls to execute the desired command. Your main process can then wait on the child process's Process Id (pid). The timeout can be achieve by generating a SIGALRM using the alarm call before the wait call.
If the sub process times out you can kill it using the kill command. Try first with SIGTERM, if that fails you can try again will SIGKILL, this will certainly kill the child process.
Some more information on fork and exec can be found here
I did not try boost::process, as it is not part of boost. I did however try ACE_Process, which showed some strange behavior (the time-outs sometimes worked and sometimes did not work). So I wrote a simple std::system replacement, that polls for the status of the running process (effectively removing the problems with process-wide signals and alarms on a multi threading process). I also use boost::this_thread::sleep(), so that boost::thread::interrupt() should work as an alternative or in addition to the time-out.
Stackoverflow.com does not work very good with my Firefox under Debian (in fact, I could not reply at all, I had to start Windows in a VM) or Opera (in my VM), so I'm unable to post the code in a readable manner. My prototype (before I moved it to the actual application) is available here: http://www.jgaa.com/files/ExternProcess.cpp
You can try to look at Boost.Process:
Where is Boost.Process?
I have been waiting for a long time for such a class.
If you are willing to use Qt, a nice portable solution is QProcess:
http://doc.trolltech.com/4.1/qprocess.html
Of course, you can also make your own system-specific solution like Let_Me_Be suggests.
Anyway you'd probably have to get rid of the system() function call and replace it by a more powerful alternative.