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.
Related
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.
I have installed a program ("CmisSync.exe") that runs as a small icon in the Windows system tray.
From C# I want to start it, and then exit it gracefully (as if a user had clicked "Exit" in the program's menu). Here is my attempt:
Process process = Process.Start(#"C:\Programs\CmisSync\CmisSync.exe");
// Wait for CmisSync's configuration/UI to start properly.
Thread.Sleep(5000);
// Close as if the user had clicked "Exit".
process.CloseMainWindow();
// Wait for CmisSync to finish what it is doing and exit normally.
// This might take a few minutes if a big sync is going on.
process.WaitForExit();
Unfortunately, CloseMainWindow does not make the program stop.
Maybe it is due to the program not actually have a main window? It only runs in the tray.
Close does not make the program stop either, by design.
Kill is not graceful, it does not let the program finish its current UI loop. Unlike the UNIX equivalent, the command does not seem to accept arguments indicating how brutal the kill should be.
The tray icon is implemented using System.Windows.Forms.Form
Yes, as you have discovered Process.CloseMainWindow only closes a program with a main window i.e you will most likely find the MainWindowHandle will be IntPtr.Zero
Process.CloseMainWindow Method ()
Closes a process that has a user interface by sending a close
message to its main window
Additionally, AFAIK WM_CLOSE or any other message wont help you either
However, you could create a message only window, or have your mainwindow set to invisible so you could message it in standard ways or call Process.CloseMainWindow.
However there are also many other IPC techniques you could use to the same affect, or even WCF. Anyway, since you're in control of the sync tray icon program, you can employ anything really (well except techniques that require a window evidently)
Interprocess Communications
Update
Since its open source, you can either edit as desired or have a look at the internals of it and you might find a way to gracefully close it.
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 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.