I have a winform app in C# with has to create an SQLLocalDB instance at first run.
I saw that this process was taking some time in some older PC´s and some users thought that the app had crashed.
I created a splashscreen form that lets the user know that the app is creating the instance but i dont know how i cant check when the process has ended and close the splashscreen.
I have a class with the following code to create the instance:
static private void ExecCmdInstance()
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/c sqllocaldb create MSSQLLocalDB -s";
process.StartInfo = startInfo;
process.Start();
}
Can anyone point me in the right direction please?
Thanks in advance.
You could use:
process.WaitForExit();
But be aware that it will block your gui thread. You might start the process on a different thread, so your gui isn't blocked.
Related
I have been trying to write a quick script for my unity VR game to begin recording from an Azure Kinect camera at runtime, and close this script/recording on the close of application. To run their demo recording application, you run k4arecorder.exe output.mkv in a command prompt, and then pressing Ctrl-C to close the camera, which allows the program to save the file properly (see Azure Kinect SDK).
I have been able to successfully open the script and begin recording from the camera with the following code, but I have not been able to enter Ctrl-C (or any text at all) on the popup command prompt in order to stop the camera from running. And I can't use Process.StandardInput.Close() as I am running this with useShellExecute=True
The .exe saves the camera recording after Ctrl-C input, so I do need to close the stdin somehow before stopping the program entirely.
ProcessStartInfo startInfo;
Process process;
void Start()
{
startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Program Files\Azure Kinect SDK v1.4.1\tools\k4arecorder.exe";
startInfo.Arguments = System.IO.Directory.GetCurrentDirectory() + "\\output_testing.mkv";
process = new Process {StartInfo = startInfo};
process.Start();
}
I've also tried a different approach, redirecting the StandardInput, but then I don't see any text at all on the popup command prompt, and my attempts to close stdin and print anything to the command prompt have also not worked. For example, I never see anything in the command prompt running:
ProcessStartInfo startInfo;
Process process;
void Start()
{
startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Program Files\Azure Kinect SDK v1.4.1\tools\k4arecorder.exe";
startInfo.Arguments = System.IO.Directory.GetCurrentDirectory() + "\\output_testing.mkv";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.CreateNoWindow = false;
process = new Process {StartInfo = startInfo};
process.Start();
process.StandardInput.WriteLine("testing");
string output = process.StandardOutput.ReadToEnd();
UnityEngine.Debug.Log(output);
}
void OnApplicationQuit()
{
// this will just perpetually wait until I close the window cause cntrl-c not going thru
process.StandardInput.Close();
process.WaitForExit();
process.Close();
}
Any tips immensely appreciated! I feel like there must be a way past this with either method, but I'm coming up short. This is Unity 2019.4.1f1 and Azure Kinect SDK v1.4.1 (though I don't think this is a bug).
Hi one thing that worked for me is using:
void OnApplicationQuit() { process.CloseMainWindow(); }
I am trying to automate HandbrakeCLI using C# via the System.Diagnostics.Process class. However, as long as my program is trying to run the process, it seems like the process never advances.
Here is my process setup:
Process process = new System.Diagnostics.Process();
ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.FileName = parameters.HandbrakeLocation;
startInfo.Arguments = arguments;
process.StartInfo = startInfo;
process.Start();
string output = string.Empty;
while ((output = process.StandardOutput.ReadLine()) != null)
{
Debug.WriteLine(output);
}
process.WaitForExit();
HandbrakeCLI.exe does appear in my processes list. The Debug.WriteLine(output); line continually prints out "Encoding: task 1 of 1, 0.00 %" and the process never completes. If I kill my C# app then HandbrakeCLI instantly shoots up from 7,000k in memory to 145,000k and then does the encoding that I want it to do. Its like my C# app is holding it back.
I have tried to use Read() instead of ReadLine() and I have tried flushing the StandardOutput stream before and after the read with no success. I have a suspicion that since HandbrakeCLI overwrites stdout when it writes the encoding progress, that it won't act like a normal process when automated via C#.
I figured it out. I was redirecting stderr to my C# application, but not consuming it. The process was hanging until stderr was consumed.
I run a command from the command window like this:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C " + command + "> " + userProfile + #"\cmdoutput.txt";
process.StartInfo = startInfo;
process.Start();
The next line of code reads the text file and manipulates the data as needed. However, if I don't wait for the cmd process to end it will read an empty text file. I have thought of:
Not using a text file
This won't work due to other restrictions I have, it does need to be put in a text file
Wait a few seconds
I don't know how long the command will take, and time-based solutions are generally bad anyway.
Check if the command prompt process is running
The user may be running another command prompt for whatever reason
The System.Diagnostics.Process class has a method, WaitForExit. As I understand your question, that should do what you're looking for.
You should be able to just do,
process.Start();
process.WaitForExit();
You can also pass an int for a timeout, if necessary.
This, of course, assumes that the application you're running will exit after it's done. If that's not the case (reconsider that!), you'll have to do something else, like polling.
I need to get process id of the newly created process with help of ProcessStartInfo class
here's my code
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "chrome.exe";
startInfo.Arguments = "--app=http://www.google.com/";
Process p = new Process();
p.StartInfo = startInfo;
p.Start();
Console.WriteLine(p.Id);
However it return an ID which is not the id of the process chrome.exe process. I have verified the presence of chrome.exe process in PowerShell with different Process ID
Thanks in Advance.
Chrome will run multiple processes with one parent process creating a number of child processes. When you run Chrome from the command line your new Chrome process will most likely communicate with an existing Chrome process (the parent I guess) and then exit which explains the behavior you see.
I want to use shell executable in order to respect user preferences of application to be started, but I also need to know when that particular application is closed.
Process editProcess = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = filename;
startInfo.Verb = "edit";
startInfo.UseShellExecute = true;
editProcess.StartInfo = startInfo;
// start the default editor
editProcess.Start();
editProcess.WaitForExit();
WaitForExit seems to return when the shell process exits and not when the real process exits.
Is there a better way of knowing when started application is exited than manually parsing registry, finding correct application to start and explicitly start that app without shell execute?
Handle the process exited event:
editProcess.Exited += process_Exited;