Wait for cmd command to end before continuing - c#

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.

Related

How to run c# console application .exe in background?

I'm trying to simulate the updating of a database using commands in cmd but I need to be able to run the .exe that calls these from a cmd and continue to use that same cmd window.
I've attempted to just hide the window that Process will create, which works fine, however when I run myFile.exe it hangs up the cmd window used to run it until the process is finished. This is a problem because when completed my code will be running for hours at a time and I would rather not keep a dead cmd window open just to run the application.
Currently ProcessWindowStyle.Hidden is what I am using to call the command and hide the window, the command sets the first value in my database to the numbers 0-25 every half second but I can't use the cmd window until it reaches 25 and exits the application.
static void Main(string[] args)
{
int Number_Of_Args = args.Length;
int[] Arguments = Check_Args(args, Number_Of_Args);
Run_Command(Arguments);
}
public static void Run_Command(int[] Arguments)
{
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";
for (int i = 0; i <=25 ; i++)
{
startInfo.Arguments = "/C dbset 1 = " + i.ToString();
process.StartInfo = startInfo;
process.Start();
Thread.Sleep(500);
}
}
When complete I need the for loop to be a while loop that will continuously change the database values and therefor having it hang in the cmd window is not ideal. My final goal is be able to call my application from cmd with "C:\filelocation Simulation.exe arg1 arg2 arg3" and have it start running and updating the database while I go about whatever other business I have with the cmd window at the time.
EDIT: I can call Start Simulation.exe and it will open a new cmd window and run the code in a new window and leaves me in control of the original window. If I could either have Start Simulation.exe hide the new cmd window OR have the code default to Start a new window when called simply as Simulation.exe that could be what I need, although having both would be the best, like previously stated, so that I can run the command and not lose control of the current cmd window.
I did some searching and if I understood you right, I think you can achieve what you want with:
start /B ConsoleApp.exe
Source:
How can I execute a Windows command line in background?

check for process end to close splashscreen

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.

How to send keys to a process that started a bat file in C#?

This process starts a bat file that runs for a few seconds, after that I need to pass it a parameter for continue.
It is not possible to pass this parameter as an input parameter for the bat file.
This is as far as I go
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
Process = Process.Start(ProcessInfo);
Now after a few seconds a menu is appearing and I have to input my choice to continue.
How can I do that?
To send input to a process you use: Process.StandardInput
See full documentation here: https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardinput(v=vs.110).aspx
You could use WaitForInputIdle() if your process got a guid.
Process.WaitForInputIdle();
Process.StandardInput.Write("Someinput");

Why won't "cmd.exe /C command" end when called via Process.Start()?

I'm trying to run a command via command prompt from an ASP.Net web application. I can see the process start in task manager on the web server, however the process just sits there and never exits nor does it run the commands I specified.
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C " +command;
startInfo.UserName = "myuser";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.Domain = "mydomain";
startInfo.CreateNoWindow = true;
String pass = "mypass";
System.Security.SecureString secPass = new System.Security.SecureString();
foreach (char c in pass.ToCharArray())
{
secPass.AppendChar(c);
}
secPass.MakeReadOnly();
startInfo.Password = secPass;
process.StartInfo = startInfo;
process.Start();
//output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
process.Close();
I've tried both with and without reading the standard output.
The application will hang on process.WaitForExit(); until I kill the process via task manager.
I think we need to understand what commands you are actually trying to process in order to determine what's going on. Also we need to know what OS the server is running.
For example, I did see in your comments where you tried "echo test > C:\test.txt" Under Windows Server 2008 (and Windows 7) the root directory requires administrator permissions in order to create files. If this is executing under IIS, my guess is that your IIS user isn't an administrator and you are getting security exceptions.
Also, a number of commands may require elevated priviledges due to UAC. I don't remember exactly, but I'm guessing that if those commands are being caught by UAC then the process is waiting for UAC confirmation... Which I believe you cannot supply via a command line.
This type of problem won't be seen if you log into the machine and execute it directly... unless you are logging in with the worker process user account.
So, the very first thing you need to do is figure out what it is you are trying to run and see if the user the worker process is executing under can even perform those actions. Security is there to protect you, so be careful about granting additional permissions to the user.
The reason why it might work on one machine versus another again depends on the OS's those machines are running and the configuration of the user the commands are executing under.
If this is truly a security issue, as I suspect, then you should post a question on serverfault.com to ask what permission sets you need to execute various commands under your worker process user.
You might look at the machines event logs to see if there were any warnings or errors thrown about the command. Sometimes things like this can show up there to give you a bit more information as to what happened.
Once passed to CMD, the control has passed to the shell. It's better to add a close it like this:
private void closeSubProcess()
{
Process[] currentProcesses = Process.GetProcesses();
foreach (Process p in currentProcesses)
{
string s = p.ProcessName;
s = s.ToLower();
if (s.CompareTo("YOURPROGRAMNAMEHERE") == 0)
{
p.CloseMainWindow();
p.Close();
}
}
}
I am calling cmd.exe to start a node module in Windows. npm obviously must be installed first, along with the node module I need, and then I can call the module with args in C#. Problem was, the cmd.exe would not shut off, I'd have to use Task Mgr (just like this question!).
//This requires npm, and the module installed by npm...
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = true; //closes command window
psi.Arguments = "/c <nodemodulename>" + file1 + ".txt " + file2 + ".log";
Process p = Process.Start(psi);
p.Close();
The /c argument was key to closing down cmd.exe. When I started out, I had put in the /K argument, which keeps the darned thing running. Solved. Hope this helps. (This is like ancient, but we always forget)

ProcessStartInfo.UseShellExecute = true and waiting for process exit

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;

Categories

Resources