We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Monitoring a process is running

kachan
kachan asked
on
Medium Priority
331 Views
Last Modified: 2012-06-27
I want to wait a program to monitor another program (WinFax Pro 8.0) to see if it is currently responding. The WinFax Pro 8.0 has always stop working, and when I press CTL-ALT-DEL it always comes up with not responding for me. Now anyone can show me how to detect this situation and let me know how to kill the process?? Many Thanks
Comment
Watch Question

Top Expert 2009

Commented:
There are different approaches for doing that depending on the OS you use. Are you using Win95, Win98 or WinNT?

Author

Commented:
I am using Win 95, but I think it would be nice to know how to done it over NT also.... However, was there any different in doing this between 95 and 98??
Engineer
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Top Expert 2009

Commented:
First, there's a major difference doing this in NT or Win95. I'm not sure about Win98, haven't tested my code yet on it and I haven't seen an updated SDK yet.

About TerminateProcess. One advice: don't use it, unless in extreme circumstances. BTW, you'll need the processhandle to do that, and that is the "hard" part. But I'll come to that later. This is what Microsoft says about the function TerminateProcess in the "Remarks" section:

The TerminateProcess function is used to unconditionally cause a process to exit. Use it only in extreme circumstances. The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess.

TerminateProcess causes all threads within a process to terminate, and causes a process to exit, but DLLs attached to the process are not notified that the process is terminating.

Terminating a process causes the following:

1. All of the object handles opened by the process are closed.

2. All of the threads in the process terminate their execution.

3. The state of the process object becomes signaled, satisfying any threads that had been waiting for the process to terminate.

4. The states of all threads of the process become signaled, satisfying any threads that had been waiting for the threads to terminate.

5. The termination status of the process changes from STILL_ACTIVE to the exit value of the process.

Terminating a process does not cause child processes to be terminated.

Terminating a process does not necessarily remove the process object from the system. A process object is deleted when the last handle to the process is closed.


Well, now that's clear, what SHOULD you use? I recommend as a first step: ExitProcess. That call assures a clean shutdown of the process. This is what Microsoft about it in the "Remarks" section:

ExitProcess is the preferred method of ending a process. This function provides a clean process shutdown. This includes calling the entry-point function of all attached dynamic-link libraries (DLLs) with a value indicating that the process is detaching from the DLL. If a process terminates by calling TerminateProcess, the DLLs that the process is attached to are not notified of the process termination.

After all attached DLLs have executed any process termination value, this function terminates the current process.

Terminating a process causes the following:

1. All of the object handles opened by the process are closed.

2. All of the threads in the process terminate their execution.

3. The state of the process object becomes signaled, satisfying any threads that had been waiting for the process to terminate.

4. The states of all threads of the process become signaled, satisfying any threads that had been waiting for the threads to terminate.

5. The termination status of the process changes from STILL_ACTIVE to the exit value of the process.

Terminating a process does not cause child processes to be terminated.

Terminating a process does not necessarily remove the process object from the operating system. A process object is deleted when the last handle to the process is closed.

The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

· During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.

· Only one thread in a process can be in a DLL initialization or detach routine at a time.

· ExitProcess does not return until no threads are in their DLL initialization or detach routines.


Well, now that is clear as well, I think I'll give you best way to do it as well. That is, using SendMessage with WM_QUIT. That way an application gets normally informed that is should end it's message loop and close the window. You'll have to send that message to the main window of a process.
Actually, you should use a combination of these three techniques. First you should send a dummy-message to see if the process is responding. If not, you first try to end the process nicely by using WM_QUIT. If that doesn't work, you try ExitProcess. When the process still isn't responding, you try ProcessTerminate.

Getting these functions working, you'll need some information. At least the Window handle and the process id belonging to that window-handle. In Win95 you can use the FindWindow and/or GetWindow functions to retrieve handles to the functions and you can use the Toolhelp32 functions (in particular CreateToolhelp32Snapshot, Process32First and Process32Next). In WinNT you can use the FindWindow/GetWindow functions as well but you won't be able to use the Toolhelp32 functions. You'll need to do it with a Registry key (!) which only exists in memory, not on disk. It's HKEY_PERFORMANCE_DATA or (I'm not sure...) HKEY_DYN_DATA. I will look up the PViewer source when you need it.

Regards, Abel


PS: Thui, I'm not sure what you mean with SendMessage Timeout(). I don't remember (and couldn't find) that message/function. No offence, just curious :)

Author

Commented:
abel,

Thank you very much for your kind contribution. If you can show me the source for doing all that, I will be much appreciate.

Many Thanks

Commented:
abel, it seems to me your concern about TerminateProcess, while well founded in general, is irrelevent to this question: the question was how to terminate a process which isn't reponding (and therefore can't process a WM_QUIT message). ExitProcess can't be used to terminate another process - only yourself, So TerminateProcess is the only option.

And how would one use toolhelp or performance data to detect the process isn't responding? I am not saying that's wrong, I just have never heard of it, I always assumed the system used SendMessageTimeout to do it as thui said. SendMessageTimeout is like SendMessage except that if the target process hasn't processed the emssage within a specified time it returns.

kachan: for 200 points, it's perfectly reasonable to expect someone should give you either a very detailed answer or example code (or pointers to good example code) which will allow you to proceed. If you aren't satisfied with the answer thui has provided, you should reject it and reopen the question. Until you do so, only thui can get the points for this question, so there's no motivation for abel (or myself or anyone else) to work out a more detailed answer which would actually help you solve the problem.
Top Expert 2009

Commented:
alamo,
I can't say nothing more than "you are right". It was erroneous of me to post about "ExitProcess". Although I know the details about it, I forgot when posting it here. Unless you make a dll which attaches to a process (like when "hooking") you cannot use ExitProcess to kill another process.
About SendMessageTimeout, I just didn't read/look too careful. I thought it was "SendMessage Timeout()" in stead of "SendMessageTimeout()" (watch the space), which is indeed the best way of doing this.

The Toolhelp functions are for making things easier. Using EnumWindows, FindWindow and/or GetWindow in conjunction with GetWindowThreadProcessId and TerminateProcess is a lot more difficult (and has more ambiguities) than using the Toolhelp functions with TerminateProcess. At least to my opinion. You can't use them to determine if a process is not responding, SendMessageTimeout is the easiest for that goal, I think.

kachan: I would like to help you further on this, or maybe alamo, thui, or a combination, but you'll have to make a choice by either rejecting thui's answer or asking him/her to give more info.

Regards, Abel
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.