How to gracefully stop a server process which is listening on a pipe on Windows - windows

I have a named pipe server similar to the MSDN sample at http://msdn.microsoft.com/en-us/library/windows/desktop/aa365588(v=vs.85).aspx and would like to allow clients to send an "exit" message which causes the server to gracefully stop.
So in the "InstanceThread()", if a special message is received, I would like to make the server stop.
I tried to stop the call to ConnectNamedPipe() in the main thread from the separate thread for "InstanceThread()" by closing the pipe handle, but this does not work.
I already tried various things, among others closing the overall pipe, exiting directly from the InstanceThread, ... but none of them causes the call to ConnectNamedPipe() to stop.
I played with SetNamedPipeHandleState(), but it complicates the implementation hugely, also using overlapped I/O seems overkill for this simple requirement.
So is there an easier way to get ConnectNamedPipe() to return when the server process should be stopped and not wait endlessly for client connections?

If you don't need to support Windows XP, you could try using CancelSynchronousIo.
If the process is exiting, you don't need to do anything; the thread will be terminated when Windows tears down the process.
Alternatively, you could make the call to ConnectNamedPipe exit simply by connecting to the named pipe yourself.

Related

Tuxedo tmshutdown stops server but process still exists

i've got problem with tuxedo tmshutdown command. One of processes still runs (with huge cpu usage) though tmshutdown stops it succesfull. There is also one opened IPC shared memory which i can close when I kill existing process. There are other servers but only this one is problematic. Is it possible that the problem is in code (tpsvrdone is exiting without errors)?
Tmshudown normally sends a SIGTERM signal to tuxedo serves unless you use -k KILL (which sends a SIGKILL)
If the source code of the Tuxedo server implements a handler of the signal, you could get the behavior you explained.
http://www.thegeekstuff.com/2012/03/catch-signals-sample-c-code/
Also, if it is not possible to shutdown a server, or remove a service advertisement, a diagnostic is written on the ULOG.

In Windows 7, how to send a Ctrl-C or Ctrl-Break to a separate process

Our group has long running processes which run daily. The processes are typically started at 9pm on any given day and run until 7pm the next day. Thus they typically run 22hrs/day. They are started by scheduled tasks on servers under a particular generic user ID, and they start and run regardless of whether or not that user ID is logged on. Thus, they are windowless console executables.
The tasks orchestrate computations running on a large server farm. Generally these controlling tasks run uninterrupted for the full 22hrs/day. However, we often have a need to stop and restart these processes. Because they control a multitude of tasks running on our server farm, it is important that they be shut down cleanly, so that they can stop and shut down all the server farm processes. Which brings me to our problem.
The controlling process has been programmed to respond to ctrl-C and ctrl-break signals. This works fine when the process is manually started in a console where we have access to the console and can "type" ctrl-c or ctrl-break in the console window. However, as mentioned, the processes typically run as windowless scheduled tasks. Hence we cannot "type" anything into a non-existent console window. Because they are console processes that execute without a logon process, the also must be able to execute in a completely windowless environment. So, how do we set up the process to listen for a shut-down signal?
While the process does indeed listen for a ctrl-C and ctrl-break signal, I can see no way to send that signal to a process. This seems to be a fundamental problem in Windows, or am I wrong? I am aware of SendSignal.exe, but so far have been unable to get it to work. It fails as follows:
>SendSignal 26320
Sending signal to process 26320...
CreateRemoteThread failed with 0x00000005.
StartRemoteThread failed with 0x00000005.
0x00000005 == Access is denied.
Trying "taskkill" without -F results in:
>taskkill /PID 24840
ERROR: The process with PID 24840 could not be terminated.
Reason: This process can only be terminated forcefully (with /F option).
All other "kill" functions kill the process immediately rather than sending a signal.
One possible solution would be a file-watch based solution: create a watch for some modification of a specific file. But this is a hack and we would prefer to do it with appropriate signaling. Has anyone solved this issue? It seems to be so very basic a functionality, and it is certainly trivial to do it in a Unix environment. Surely Microsoft has provided SOME mechanism to allow clean shut down of a windowless executable?
I am aware of the thread below, whose question is virtually identical (save for the specification of why the answer is necessary, i.e. why one needs to be able to do this for a windowless, console-less process), but there is no answer there excpet for "use SendSignal", which, as I said, does not work for us:
Can I send a ctrl-C (SIGINT) to an application on Windows?
There are other similar questions, but no answers as yet.
Any help appreciated.
[Upgrading #Anon's comment to an answer for visibility]
windows-kill worked perfectly and managed to resolve access denial issues faced with SendSignal. A privileged user would have to run it as well of course.
windows-kill also supports both ctrl-c and ctrl-break signals.

How to check if a given process is running when having its handle

I am using ShellExecuteEx to start an application.
After successful start im reading TShellExecuteInfo.hProcess to obtain a handle of the started process.
I would like to periodically check if the process started by my application is still running.
Two or more processess with the same name can run simultaneously and I want to be sure that my application is checking the correct process.
I want to be able to do this on Windows systems from Windows 2000 to above.
I know that there is WinAPI function GetProcessId which is doing exactly what I want but it does not support Windows 2000.
Thank you for your answers.
Call WaitForSingleObject on that handle, and use a timeout parameter of zero. If the process is still running, the function will return Wait_Timeout; if the process has terminated, then it will return Wait_Object_0 (because process termination causes its handles to become signaled.)
If you want to know what the exit status of the process is, then call GetExitCodeProcess.

C# catch kill command

how can I catch windows taskkill command in order to prevent it?
You cannot prevent your process being killed. The only way to keep a program alive is to have a second Watchdog application that is constantly pooling that process to ensure it's running.
So, you have two Applications; AppA (Main) and AppB (Watchdog).
AppA checks if AppB is running. If
not, AppA starts AppB.
AppB checks if AppA is running. If
not, AppB starts AppA.
But this is usually a design for a malicious process, so I hope you're not doing anything untoward.
You can see the following events in the message queue when End process is clicked:
WM_CLOSE // UI app
CTRL_CLOSE_EVENT //
Console app
But if your application does not close in a timely manner, then the kill command will be sent, which cannot be captured.
I'm pretty sure it is not possible, otherwise a single application could stop windows from ever shutting down. Even when the process is hung, killing it in task manager eventually works. If it was possible, malicous software, etc would probably have a hey-day using it - not only could they take control of various parts of your PC, they'd make sure you could never get it back again.

Restarting a windows service

I want to schedule a restart of my custom services
automatically using a batch file with net stop, net start.
When net stop runs does it abort anything that is being done
immediately?
Just wondering what will happen if in the middle of processing?
Malcolm
It will call into your code asynchronously and it will be up to you to deal with it. You could enact a clean or abort as you see fit.
It really depends on how the service is implemented. "net stop" essentially calls into the service and says "would you kindly stop". Most services will comply with this command and stop in a timely fashion. However there are the bad services which do not comply and refuse to stop. In this case, net stop will take no further action.
It really depends on the service. I suspect most will try to get into a good state before stopping. It isn't a kill.
A service registers to receive events (via RegisterServiceCtrlHandler). When you do a net stop the registered callback will receive a callback with the SERVICE_CONTROL_STOP operation. How the service responds to that callback is up to the service implementation. It would make sense for the service to do regular application shutdown processing.
Like the others said, when you call net stop, it will invoke the OnStop in the Windows Service. If the OnStop does not kill all the threads in the app, or doesn't shut everything down properly, your service might not stop. (I've seen this happen in one of our WCF services: we didn't close the ServiceHost in OnStop, and therefore, the app would not stop at our command - we'd have to kill the process by hand.)
One common pattern I've seen is to try calling stop on the service, and if it doesn't die within a timeout (10 seconds), kill the process by force. As an alternative to batch files, PowerShell has some pretty good support for dealing with services.

Resources