I'm trying to shutdown a process a bit more gracefully than what the process.Kill(true), method does.
I have a console application, where I start start another process "myProcess" (which is not an application I have sourcecode for), which I want to be able to shutdown, as if pressing ctrl+c in the console.
"myProcess" is essentially pinging a receiver at a fixed interval.
When I shut it down using ctrl+c the "myProcess" shuts down gracefully, sending an "i am offline now" request to a receiver.
However, when I shut it down using kill(true), it doesn't get to send the offline request, and the receiver stops receiving pings, but doesn't mark it as online.
Note I don't have control over the source for myProcess nor the receiver, so I can't change any behaviour in those.
I have tried using waitForExit(), waitForExit(0) and kill(), all of which only stops my debugging session, but myProcess keeps running.
Searching for a solution I come across answers suggestion these methods, and using GenerateConsoleCtrlEvent, to send the ctrl+c event programmatically. However my console app does not recognize that method, and I can't seem to find any way to use it.
I assume, because the answers were fairly old, that it is no longer an option in .NET 6.
Does anyone know, how to shutdown a process gracefully, wither a spawned chilprocess, or the self process Process.GetCurrentProcess()?
Looks something that needs handling of SIGTERMS.
Check this out
You can try using CloseMainWindow, read the docs to see if it is suitable for your use case.
Related
I want to watch a process (in another application) that might fail and relaunch it if it fail. It's working if the process is exited. But if the window that say the programe not seem to respond terminate now or wait is open.
My process is dead but as long as i don't click on close program i don't get any information about this.
My process are on multiple VM it's a process that update my client application and i try to not force my support to connect in every client to click on Close program every time a little bug happend.
Is their any event that can tell me window ask to close this process?
Is their a way to achive this? Right know I'm thinking about making a ping with my process using some message. But i would like a solution that don't involve modify both app and only the watcher app. Plus i'm not sure if a process is in "Close now" State have all thread stop or if my read message thread will continu to respond while my main thread will be dead.
I have this program that several users on the same computer is using (windows 2008 server environment with remote desktop clients).
When the program is ended normally, it deletes a special file in its working directory.
I need to be able to send all instances of this program a command to cleanly shut down (so that it deletes the file at exit).
What would be the best way to do this, and how?
I assume getting the pids for each instance is a start, but then what?
Anyone have any good ideas?
Edit: Forgot to mention, it's a WinForm (not a command line) program.
Edit2: My comment was too long, so I guess it's best to just edit the question instead...
The file it's deleting is actually a file containing it's pid.
The reason for having this file is to make sure that the user doesn't attempt to start the program twice with the same arguments (login information).
The main program (control center) that is actually starting the client program is keeping track of the pidfile in the users directory.
If it discovers the file it reads the pid and tries to see if the pid exists.
If not, it actually does delete the file and is letting the user start the client window.
I guess by using that procedure, I simply could make it look for all pids asociated with my application and simply kill them, ut I'd prefere to be able to send a shutdown command, as that would also notify the user in an IM that the program is shutting down for whatever the reason given. (Client initiated, remote server initiated, or, as in this case "Local server initiated").
A Mutex is something that represents mutual exclusion. I don't think that is really what you want in this case. It's not really modelling what you want; plus only one application at time would be able to shut down. I would recommend using a named EventWaitHandle to model one application sending events (shutdown events) to other applications. If you use a manual reset event (by using EventResetMode.ManualReset when you create an EventWaitHandle object.
You would do this on a background thread that, when signalled, would marshal something over to the UI thread (via Control.BeginInvoke) to communicate to the main form that it needs to shut down.
You could use a system wide event by using a Mutex
See the example on the linked page in the MSDN
I'm starting a external application with System.Diagnostics.Process, this external process at one moment opens up a dialog where user has type something and then click OK. What i need is to wait with my application(the one where i started the external process) until the user has inserted something and clicked OK. After that OK i have to do some more task on that external process and then close it.
Yes, it's possible. There are a number of ways to get window information starting with a process handle and/or ID. See this question and responses for getting started. You will most likely end up using P/Invoke to the Win32 API to get this accomplished but there are dozens of good examples for getting this done.
Once you have the window handle you can use a timer polling scheme to test for the presence, or in your case, presence and then the disappearance of a window.
This is possible but there are some work behind it. First you need to run your code as unmanaged code as you will need to hook on Windows OS events with the Win32 API.
So an option would be to have a loop looking for the dialog to open, pause what ever your code are doing and continue when the dialog are gone.
If the application you are starting exists after the user interacts with the dialog, then you can just call Process.WaitFroExit() and your code will not continue until the process you started has quit.
There are quite a few helpful functions for interacting with processes in the System.Diagnostics.Process class (that I assume you are using to start this external application)
I'm using the Input Simulator library to simulate input to another application using C#, this uses the SendInput API calls. Does anyone know if there is a way I can monitor the windows message queue for the external application to see if those messages have been processed?
For example, let's say I want to send the keystrokes for the word "Hello" to notepad, but I don't want my application to continue until notepad has received and processed the input and the word "Hello" has appeared in the notepad window. We'll know this has happened once the keypress messages are no longer in the message queue for notepad, but I can't work out how to find that out.
I was using the .NET SendKeys class and using SendWait, but this seems unstable and causes occasional freezes in the external application, so after weeks of trying to fix that I'm looking for a new method.
Many thanks
You can't. Calling SendInput ultimately results in posted messages which are delivered asynchronously.
Why fake input to Notepad when you can send the text direct to the edit window? Not only would it be way simpler it would be robust and synchronous.
I doubt this is even possible. So your app is running and user decides to End Process via Task Manager. Is there a method/action to save data during process.kill? I doubt there is but I had to ask.
Also, if a user shuts down/restarts PC (as in windows update/manual restart), what action would the app execute? Window_Unloaded? On this second question, I would like to find a way to ensure my app does not show up as a 'if you want to restart, kill this app' situation and want to save needed data.
Your two cents is greatly appreciated!
It's not possible to do what you want unless you have two processes; one monitoring the other one's status and do some stuff upon its termination. The watchdog process might be a Windows Service Application without GUI.
Windows sends a quit message to every opened application when normal shutdown occurs. You can run some code (usually housekeeping stuff) upon receiving the message and exit the application. It shouldn't take long or Windows will automatically ask user if they want to kill the application.
Force shutdown kills all processes immediately (in no particular/predictable order). So you can't (easily) detect it.
I suggest you to save everything needed as soon as possible to prevent data loss when the application process gets killed.
If something terminates your running app, then you don't get an opportunity to do anything, just die. You modify your app such that all data is always saved to some persistent location, so if the app dies, the persisted data remains. Obviously you have to design for this. Then if the user does a "save", you commit to the "real" datastore.
If Windows is going to reboot, it should send a message to your app, which you can handle. Not sure if this works for all GUI/console/service -type apps however.