I would like to be able to watch a process until it is terminated, and once non existent display a message, how could this be achieved?
Create/Attach to the process and then either use WaitForExit() to block until it has exited, or use the OnExited Event if you don't wish your application to block while it's waiting for the app to exit.
I heartily recommend reviewing the documentation for Process - right here
The .NET Framework has built in support for this. You need to use the Process.Start method to start the process, and then call the WaitForExit method, which will block execution of your application until the process you started has finished and closed.
Sample code:
// Start the process.
Process proc = Process.Start("notepad.exe"); // TODO: NEVER hard-code strings!!!
// Wait for the process to end.
proc.WaitForExit();
// Show your message box.
MessageBox.Show("Process finished.");
Related knowledge base article: How to wait for a shelled application to finish using Visual C#
I think this is what you want to do:
System.Diagnostics.Process process=new System.Diagnostics.Process();
process.StartInfo.FileName = "process.exe";
process.Start();
process.WaitForExit();
//process ended
MessageBox.Show("Process terminated");
Related
I want the following code to run different applications and after they have openend additional tasks.
However some applications keep an command window open whilst others do not.
e.g. outlook.exe runs just fine,
ProcessStartInfo startInfo = new ProcessStartInfo("C:\\Program Files\\Microsoft Office\\root\\Office16\\OUTLOOK.EXE");
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
But when running Visual Studio Code, the command window stays active in the background;
ProcessStartInfo startInfo = new ProcessStartInfo("C:\\Program Files (x86)\\Microsoft VS Code\\Code.exe");
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
It seems the loaded application process is the command window and not Visual Studio Code. So the command window disappears when I remove the WaitForExit(); But then i do not know when the application has loaded.
Is there another way to know if Visual Studio Code is fully loaded?
Process.WaitForExit() waits until the process you started has actually exited (as the name suggests). If this returns while the application you started is still visible, this is because the process you started is not used. For example, an existing instance of the Outlook process that is already running might be used.
If you want to wait for the process you start to be ready to accept user input, use Process.WaitForInputIdle().
Use WaitForInputIdle() to force the processing of your application to wait until the message loop has returned to the idle state. When a process with a user interface is executing, its message loop executes every time a Windows message is sent to the process by the operating system. The process then returns to the message loop. A process is said to be in an idle state when it is waiting for messages inside of a message loop. This state is useful, for example, when your application needs to wait for a starting process to finish creating its main window before the application communicates with that window.
I am creating a windowservice that starts a process where I pass multiple cmd arguments in the StartInfo.Arguments. That works fine as expected.
The problem is that when i stop the windowsservice, I need to tell the running program to shut down gracefully before the windows service stops. Because if I just kill the process the program does not save the collected data. The program that I run is the Process Monitor and it accepts the following command "/terminate".
How can I pass the /terminate argument before my windows service stops?
There is a couple of ways you can approach this solution but you can signal the process, and based on what you send with this signal it should execute its 'clean-up' code. Once it's finished, the process that spawned it should be signalled that it finished the cleanup code and can then shutdown. This of course assumes that you wrote the code for both the Window service and the process being spawned.
You can try Named pipes (https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-communication)
I managed to find a solution. In the OnStop() method in the service, I needed to create a new instance of the Process Monitor and pass the /Terminate argument:
Process process = new Process();
process.FileName = "\Procmon.exe" ;
process.StartInfo.Arguments = "/AcceptEula /Terminate";
process.Start();
With that it stoppes all the Process Monitor instances gracefully.
I am executing one .net console from another console App.
Eg MyTool.exe < input.txt
Where Input.txt will have all the input required by tool.
The input in the input file should be dyanmic, so to achive this.
I created another wrapper console App MyWrapper.exe.
This is first crating the input.txt file and then calling the MyTool.exe using .Net Process().
Content of batch file
MyTool.exe < input.txt
var proc = new Process();
proc.StartInfo.FileName = "MyBatchFIle.bat";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
Now here is the question.
Say in case of error or incorrect input, there is possibility that MyTool.exe can go to infinite loop.
So I want to detect this kind of error and stop the execution.
My plan is to execute the MyWrapper.exe from Windows scheduler.
Thanks,
Siraj
You could wait for the process to finish + Timeout. If the process did not finished within the timeout, you can kill it:
if(!proc.WaitForExit(timeout))
{
proc.Kill();
}
Another option is to communicate with the process via IPC (e.g. named pipes). But that requires the extension of both tools and increases complexity.
A third option is to communicate via files. For instance: having a status file that can be written by 'MyTool.exe' in format similar to "[process_ID] status". Then the wrapper could read that infomation periodically and kill the process, restart it or whatever is needed.
I have been trying to implement something like this, but it will time out on the wait for exit?
My objective is to open the file on the client's machine in notepad. The below code is what i originally had, but just learned taht this will only work on the server ,not the client.
public JsonResult Index()
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.FileName = "notepad";
proc.StartInfo.Arguments = #"\\share\test.XML";
proc.Start();
proc.WaitForExit();
}
Is there a way to do this?
All i am trying to do is open the test.xml file on a client's machine.
The code you have there will execute on the server side; not on the client-side. You can't open a file (or execute a program for that matter) on the client machine, from a browser. That would be a major security issue if a browser could do that.
Best thing you can do is either create a hyperlink to the file in the format file:///drive:/file.xml
Your code will start the notepad application and open the test.xml file in correctly
The notepad application will left open till it is close because you are using the WaitForExit method.
The WaitForExit method instructs the Process component to wait indefinitely for the associated process to exit.
Do you really want to use the WaitForExit in your MVC action
Please read the Remarks taken from MSDN for WaitForExit
The WaitForExit() overload is used to make the current thread wait
until the associated process terminates. This method instructs the
Process component to wait an infinite amount of time for the process
and event handlers to exit. This can cause an application to stop
responding. For example, if you call CloseMainWindow for a process
that has a user interface, the request to the operating system to
terminate the associated process might not be handled if the process
is written to never enter its message loop.
Note: In the .NET Framework version 3.5 and earlier versions, the WaitForExit() overload waited for MaxValue milliseconds (approximately
24 days), not indefinitely. Also, previous versions did not wait for
the event handlers to exit if the full MaxValue time was reached.
my weight the same and so I resolved using this
using System.Xml;
XmlTextReader reader = new XmlTextReader(
Server.MapPath("mycompany.xml"));
reader.WhitespaceHandling = WhitespaceHandling.None;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
reader.Close();
lbNodes.Items.Add("XML Document");
XmlNode xnod = xmlDoc.DocumentElement;
AddWithChildren(xnod, 1);
the complete example you can see here
http://www.codeproject.com/Articles/4902/Reading-an-XML-file-using-NET
I am starting a VLC job to record some streaming audio from within a c# function as follows (the actual args aren't relevant to the question):
Process proc = new Process();
proc.StartInfo.FileName = "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe";
proc.StartInfo.Arguments = "someArgs";
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.Start();
If all works correctly, the Start() function returns immediately and a process is started locally (i.e. VLC).
How can I get the process ID of this VLC job so I can kill it later? Using proc.Close() closes the process, but does not terminate the VLC job.
What is the most effective way to kill the VLC job? I have admin privilege locally.
How can I test that the job did start correctly? Is there some status flag on the proc object I can test?
Thanks
Andrew
The ID should be in your process object as proc.Id.
You can kill it with proc.Kill().
If there is a problem launching the process it will throw an exception (most likely a Win32Exception or an InvalidOperationException; see the help.)