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.).
Related
Following problem:
I want to start the cmd as administrator in C# with a process to get the UAC befor the code:
var process = new Process();
var ps= new ProcessStartInfo();
ps.CreateNoWindow = true;
ps.FileName = #"cmd.exe";
ps.Verb = "runas";
process.Start();
After i confirm the UAC, i want to run code. After the code i want to start the same process but this time with arguments and without the UAC. Is that possible? Target is that i get a exe with the running code. I need the exe to run the arguments in the cmd. But the UAC should pop up before the exe will be appear. (the code should run after the uac, and the arguments after code). PS: I need the administrator priviliges to run the arguments.
You can elevate the program self first. If the process has got the right, run the wix installer. You can find IsUserAdministrator here.
public static void Main()
{
var isAdmin = IsUserAdministrator();
if(isAdmin)
{
Installation();
AfterInstallation();
}
else
{
var p = new Process();
var si = p.StartInfo;
si.CreateNoWindow = true;
si.UseShellExecute = true;
si.FileName = Process.GetCurrentProcess().MainModule.FileName;
si.Verb = "runas";
p.Start(); // UAC will show here only once
}
}
I have limited knowledge about this but I think you can:
Start your application (InstanceA) without admin.
From InstanceA, run the application with admin (InstanceB). You can run InstanceB with a /Install parameter and InstaceB knows that must start the installation.
Install the application from InstanceB.
InstanceA can wait until installations is finished and then, do whatever you want.
You may need some type of communication (pipes, memory mapping, sockets...) between both instances or something what you can monitor from InstanceA (registry key...) to check if the installations is completed and if you want more control about the whole process.
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();
}
I am writing a client for my gaming community and one of the functions of this client is to launch a game via the client with parameters that will enable our community mod pack on launch.
When I press the button, the game begins to launch and as soon as the program opens (the icon pops up in the task bar), it closes instantly.
Is there something I am missing that is needed to keep the launched exe running?
Here is my code:
private void btnLaunchGame_Click(object sender, EventArgs e)
{
string armaPath = gameDir+"/Expansion/beta/";
string filename = Path.Combine(armaPath, "arma2oa.exe");
string launchParams = "-noSplash -noFilePatching -showScriptErrors \"-name=Meta\" \"-mod=I:/Steam/steamapps/common/Arma 2;expansion;expansion/beta;expansion/beta/expansion;servermods/#HC_DAYZ;servermods/#HC_WEAPONS;servermods/#HC_EXTRAS;servermods/#HC_ACE\"";
System.Diagnostics.Process.Start(filename, launchParams);
}//close Game Launch
Any ideas is appreciated!
I have a .bat file that will execute the game flawlessly with the launch args listed below, this could possibly help pinpoint the cause of my problem:
http://puu.sh/5CGKk.png (couldn't get code to paste in a readable format).
Try using Process:
Process process = new Process();
process.StartInfo.FileName = "arma2oa.exe";
process.StartInfo.Arguments = "-noSplash -noFilePatching -showScriptErrors \"-name=Meta\" \"-mod=I:/Steam/steamapps/common/Arma 2;expansion;expansion/beta;expansion/beta/expansion;servermods/#HC_DAYZ;servermods/#HC_WEAPONS;servermods/#HC_EXTRAS;servermods/#HC_ACE\"";
process.StartInfo.WorkingDirectory = gameDir + "/Expansion/beta/";
process.Start();
It may be what exe require working directory to be set. Or it will crash, unable to load resources.
If that doesn't works, then perhaps you need to add
process.WaitForInputIdle();
before exiting function running process. I don't know why, but running Acrobat Reader without this wait may sometimes cause a wierd effect: Acrobat is running, but the document, passed via arguments, is not shown. Perhaps something to do with Garbage collector or Process itself.
Try following
using (Process process = new Process())
{
ProcessStartInfo startInfo = new ProcessStartInfo("C:\Program Files\Arma2oa\Arma2oa.exe");
startInfo.Arguments = "-noSplash -noFilePatching -showScriptErrors \"-name=Meta\" \"-mod=I:/Steam/steamapps/common/Arma 2;expansion;expansion/beta;expansion/beta/expansion;servermods/#HC_DAYZ;servermods/#HC_WEAPONS;servermods/#HC_EXTRAS;servermods/#HC_ACE\"";
process.StartInfo = startInfo;
process.Start();
}
I have a windows service containing this code:
public static void ExtractTextInner(string source, string destination)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = EXTRACTOR_EXE_FILEPATH
startInfo.Arguments = "\"" + source + "\" \"" + destination + "\"";
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
int exitCode = process.ExitCode;
process.Close();
if (exitCode != 0)
{
switch (exitCode)
{
case 1:
throw new ApplicationException("IFilter Extraction Failed");
default:
throw new ApplicationException("Unknown Exit Code:" + exitCode.ToString());
}
}
}
The purpose of this code is run an IFilter extract on a document, we use a seperate process because some IFilters are notoriously flaky.
Now this code runs perfectly fine on Windows 7 and Server 2008 R2 boxes but on a Windows Server 2003 the WaitForExit immediately throws a "There is no process associated with this Process object" exception. The process does exist and completes its task without a problem.
Anyone seen this? Can anyone shed any light on why WaitForExit would thow this error?
Additional Info
If I place this code in a Console App and run it works fine on the Windws Server 2003 box as well, hence it would appear to be a specific problem running this in a Service on a Windows Server 2003 box.
When starting processes, with the System.Diagnostics.Process class, the system can either use CreateProcess or ShellExecuteEx Win32 function. When using CreateProcess only executable files can be started. When using ShellExecuteEx, any file which can be started using the "Start->Run" command from the shell.
However these are completely different ways of starting processes. ShellExecuteEx involves the shell, and can, for example, re-use an existing instance of Word or Excel to open a document, by using the information stored under the HKCR\<progid>\shell\<verb> registry key. This may involve for example using DDE to search for and then activate an existing Excel instance.
See documentation on ShellExecuteEx's SHELLEXECUTEINFO:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb759784(v=vs.85).aspx
Note that ShellExecuteEx may or may not return an hProcess depending on whether a new process was started. This is the behavior which you are seeing.
CreateProcess is a lower-level function and creates a process directly, and simply passes the equivalent arguments. It always returns a process handle.
Note: Since you seem to be starting an executable file, it is a bit surprising that no hProcess is returned by ShellExecuteEx. Nevertheless, if you want to ensure you get a process handle, using UseShellExecute = false is the correct thing to do.
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.