I want to start a new process B.exe from the current executing process A.exe.
And as soon as B.exe is launched I want to kill A.exe (the current executing process).
Though I can start B.exe I cannot close my current process i.e A.exe.
Code I use is:
//Start the BT Setup Process
ProcessStartInfo startInfo = new ProcessStartInfo(#"C:\TEST\B.exe");
Process.Start(startInfo);
//Terminate the FSA
Process[] myProcess = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
foreach (Process process in myProcess)
{
process.CloseMainWindow();
//all the windows messages has to be processed in the msg queue
//hence call to Application DoEvents forces the MSG
Application.DoEvents();
}
Why do you want to close A from B while A cat start B and then close by itself?
Process.Start("A.exe");
Process.GetCurrentProcess().Kill(); // or Application.Exit(); or anything else
If you're falling into this quest of starting a process, and kill your own process after, use Environment.Exit(0), not Application.Exit().
Try Process.Kill() instead of Process.CloseMainWindow().
I know this is old but in .net 4.0 you can do
ProcessStartInfo startInfo = new ProcessStartInfo(#"C:\TEST\B.exe");
startInfo.UseShellExecute = true;//This should not block your program
Process.Start(startInfo);
Then Application.Exit or whatever
I tested with a winforms application using the close form method after launching a console app that just blocks on Console.readline();
If you just want to close the current process you should be able to just call Application.Exit rather than looping through and closing processes.
Related
I have an updater, which is called via the main program once an update is detected (from a remote XML file), first it checks whether the process is open
if (clsProcess.ProcessName.ToLower().Contains("conkinator-bot.exe"))
{
clsProcess.CloseMainWindow();
return true;
}
(this gets run for every process until it finds it (foreach loop))
the updater then downloads the file:
client.DownloadFile(url, "Conkinator-Bot-new.exe");
and then it attempts to delete the current one and rename it:
File.Delete("Conkinator-Bot.exe");
File.Move("Conkinator-Bot-new.exe", "Conkinator-Bot.exe");
but the error that I get when this occurs is the following:
Unhandled Exception: System.UnauthorizedAccessException: Access to the path 'D:\Conkinator's Skype Tool\Conkinator-Bot.exe' is denied.
however the new version of the program DOES download.
Just because the main window is closed doesn't mean the process is over. You need to wait for the process to exit after you close the main window:
clsProcess.WaitForExit();
Ideally, you'd use a timeout - there might be something preventing the window from closing, or the process might have a faulty exit mechanism.
It is a lot easier to close the main program from inside the main program itself.
string msg = "To update the application we need to close it. Do you want to continue?";
if (DialogResult.Yes == MessageBox.Show(msg, title, MessageBoxButtons.YesNo))
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "YourUpdaterFile.exe";
psi.WindowStyle = ProcessWindowStyle.Normal;
// Assuming a lot here but to just show the options available....
psi.WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath);
Process.Start(psi);
Application.Exit();
}
Okay so ive got another one, Right now im working on a button, called installbtn in code.
Right now i have in my code.
private void installbtn_Click(object sender, EventArgs e)
{
// Access the internal exe resource pcc - the pcc is Path Copy Copy, which i am using as a
// requirement to use this software
byte[] pccFile = Properties.Resources.pcc;
// The resource pcc.exe as a binary called pcc which is then used as a byte called pccFile
string pccExe = Path.Combine(Path.GetTempPath(), "pcc.exe");
// The Executable and its filename + Extenstion
using (FileStream exeFile = new FileStream(pccExe, FileMode.Create))
exeFile.Write(pccFile, 0, pccFile.Length);
// Write the file to users temp dir
Process.Start(pccExe);
// Start the Installer
installbtn.Text = "Installing...";
StatusLabel1.Text = "Installing PCC Now...";
// Indicate on the form, the current process status.
// Here i want the application to check if pccExe has closed
// after the user has installed the component and its process "pcc.exe" exits
MessageBox.Show("Module Installed /r/nPlease Start the Application", "Application Module Installed");
installbtn.Text = "Restart Now!";
StatusLabel1.Text = "Please Restart the Application";
// and if it has then show a message box and reflect in the form
// i want it to quit and restart the application after the message box is closed
}
now when the installer finishes, i would like to be able to detect when the installer closes ("pcc.exe") after install and then reload the application once it has. Not sure if its possible but i would appreciate the help.
Thanks Shaun.
You could use Process.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
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
process.StartInfo = startInfo;
startInfo.FileName = exeToRun;
process.Start();
process.WaitForExit();
Start returns a Process object, on which you can wait (or start a thread that waits, etc.).
Im trying to be close the calculator when the user press's a key on the key board. But p.kill and p.CloseMainWindow doesn't kill the calculator, only the shell which is executed.
Process p = new Process();
p.StartInfo.FileName = "cmd";
p.StartInfo.Arguments = "/c calc ";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.Start();
Console.WriteLine("Press any key to kill Calc");
Console.ReadKey();
p.CloseMainWindow();
p.Kill();
Don't use the shell (cmd) but run the calc process directly. Setting Process.StartInfo.FileName to "calc" should do it (assuming calc.exe is on the system path).
You need to find the Calculator process and kill it. There are actually two processes created: one for the cmd and the other for Calculator. You are killing only the first one.
The other solution is to start the Calculator directly, without using cmd.
because your process is not the calc.exe process but the command prompt which executes the calc.
to find a process by name and kill it, you should use GetProcessByName,
see an example here: C# Process Process.GetProcessesByName, Kill Process and Exit Event
I am having a Java batch process which I used in C# to run process. I want to have a testcase to check whether the batch process is running or not.
I used the batch process as:
void batch_process(string process)
{
try
{
string strFilePath = Path.Combine(batch_process_path, process);
ProcessStartInfo psi = new ProcessStartInfo(strFilePath);
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.WorkingDirectory = batch_process_path;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.ErrorDialog = true;
}
}
How can this test be done?
I want to write an unit test case to check whether the process will start or not.
when you Start your new process you need to capture the returned Process, that provides access to newly started process, useful for starting, stopping, controlling, and monitoring applications.
Process exe = Process.Start(psi);
....
if exe.HasExited() ....
You could start the process using
Process process = new Process();
string strFilePath = Path.Combine(batch_process_path, process);
process.StartInfo.FileName = strFilePath;
//this line will hold this thread until the process is done.
process.WaitForExit();
then start the process on a different thread and let that thread fire an event after process.WaitForExit(); is done.
You should first start the process using the ProcessStartInfo you've just created like:
Process process = Process.Start(psi);
then you can use process.HasExited to check if the process has exited. Often, you don't need to do this, as process.WaitForExit() blocks the code until process exits.
I'm a bit unsure of the scenario from your question... but 4 techniques you can use are:
if you have started the process using var process = Process.Start(psi); then:
you can periodically check process.HasExited - http://msdn.microsoft.com/en-us/library/system.diagnostics.process.hasexited.aspx
or you can subscribe to Process.Exited - http://msdn.microsoft.com/en-us/library/system.diagnostics.process.exited.aspx
or you can block on Process.WaitForExit - http://msdn.microsoft.com/en-us/library/system.diagnostics.process.waitforexit.aspx
if your process is started in some other way and has some unique name, then you can inspect the enumeration returned by System.Diagnostics.Process.GetProcesses() to determine if your batch process is currently running.
In general... I'd prefer to use Process.Exited, but the other methods all have their place too!
I have a command line executable that is run from a C# class library. In some very rare situations the executable will hang because of the command line data passed to it. Unfortunetely this causes the application calling the c# DLL to hang whilst it waits indefinitely for the process to exit.
If the command line exe doesnt finish execution within 1 second its never going to exit. What I'd like to do is spawn a timer just after the process has started and force close the process if it hasnt exited within a few seconds.
What is the best approach here? The solution needs to have minimal impact upon performance because this command line process is the bottleneck in a highly repetitive task.
Edit: Any reason why I should use System.Timer rather than Threading.Timer or vice versa?
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = workingDirectory;
startInfo.FileName = commandLineExe;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = strArguments;
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
Please refrain from suggestions that I should try and figure out why the command line app is hanging, or that I should refactor the command line functionality into the source code. We are actively working on that problem but stability of the application needs to come first.
Just add:
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo)) {
if(!exeProcess.WaitForExit(1000))
exeProcess.Kill();
}