Process.Start cmd results in "is not recognized" - c#

When launching an application directly, the application is launched, but when launched through cmd - it's not.
For example:
Works:
Process.Start("firefox");
Doesn't work:
Process.Start(
new ProcessStartInfo
{
FileName = "cmd",
Arguments = "/k firefox"
});
I've tried setting UseShellExecute to true, but to no avail. I still get:
'firefox' is not recognized as an internal or external command,
operable program or batch file.
So, yes, I can specify the complete path. But is there a way to avoid that? Or in other words - what's the difference between the two that makes the second fail?

Haven't tested it but I guess you are probably looking for the start command:
Process.Start(
new ProcessStartInfo
{
FileName = "cmd",
Arguments = "/k start firefox"
});
As a tip, simply run "firefox" in a command prompt -> you'd get the same error message.

Related

How to pass arguments to command line utility using c#?

I'm writing an application, and at one point it launches win-acme and needs to pass some parametres to it. I'm successfully opening powershell and launching win-acme, but it doesn't pass arguments to it. So, I have this code:
Process wacsProcess = Process.Start(new ProcessStartInfo
{
FileName = #"C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe",
Arguments = (#"cd C:\inetpub\letsencrypt ; .\wacs.exe ; N"),
RedirectStandardOutput = true,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
});
File.WriteAllText(".\\OutPutAfterFirstLaunch.txt",
wacsProcess.StandardOutput.ReadToEnd());
It opens command-line utility, but doesn't give it the last parametr "N". I guess that is because I'm passing this parametr to the powershell, but it's still working with win-acme.
It looks like this:
Is there a way to pass an argument to the command line utility using C#?
This is how this application is designed. It is meant to be interactive for new certificates. Please see the documentation with all of the allowed command-line arguments: https://www.win-acme.com/reference/cli
Is there a particular reason that you must launch the process from powershell?
You should be able to read the stdout of the process if you launch it directly the same way as if you were reading the output from your powershell window (the output powershell displays is just the stdout of the process anyways.)
You can also try passing the N parameter with the executable,
Arguments = (#"cd C:\inetpub\letsencrypt ; .\wacs.exe N;"),

Use CMD commands in C# For showing Tasklist

I need to find the PID number for a process using C# and tasklist in the CMD.
the PID number needs to be put into a textbox in a c# form.
The code for finding the pid number in Command prompt is this.
for /f "tokens=1,2" %a in (' Tasklist /fi "imagename eq notepad.exe" /nh') do #echo %b
But I donĀ“t know how to integrate CMD commands into C# winform.
You can achieve the same thing in .NET by using Process.GetProcessesByName and then outputting the process Id:
foreach (var p in Process.GetProcessesByName("notepad"))
{
Console.WriteLine(p.Id);
}
Alternatively, if you really want to use the cmd window and capture the output, you can create a process that will run cmd.exe and pass it the command line you want to execute (add a /C at the beginning, which tells cmd.exe to close the cmd window after running). You also want to RedirectStandardOutput, which allows you to capture the output of the command that was run. Then you can use proc.StandardOutput.ReadLine() to get each line that was returned:
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/C for /f \"tokens=1,2\" %a in " +
"('Tasklist /fi \"imagename eq notepad.exe\" /nh') do #echo %b",
RedirectStandardOutput = true,
UseShellExecute = false,
}
};
proc.Start();
proc.WaitForExit();
while (!proc.StandardOutput.EndOfStream)
{
Console.WriteLine(proc.StandardOutput.ReadLine());
}
You can certainly initiate a command prompt window ( Console ) and capture its stdout and stderr streams to grab the data and then parse it and show it in a windows forms control,
at the same time, usually in a case like this the Process class part of standard .NET Framework is used to retrieve any information of a running process on thw Windows machine,
have a look at this methos in MSDN for example: Process.GetProcessesByName or any other method of the Process class, that way you can do it without running any command in any console window.

Getting CMD output via Process.Start with UseShellExecute = true in C#

I need to run an elevated command in my c# application and get the output.
I'm creating a new System.Diagnostics.Process instance, coupled with a new System.Diagnostics.ProcessStartInfo instance.
The command is being sent to cmd.exe, and unfortunately may require elevated user access (meaning UseShellExecute = true and Verb = "runas" must be present).
As a result of using UseShellExecute = true, RedirectStandardOutput will not work.
It's important I record the output of the command, but the only way I can see of getting this is adding something like > output.txt to the argument list, then calling System.IO.File.ReadAllText to read the result.
Can anyone think of less hacky way?

Check if process indirectly resulted in an error

I have the following code that I'm using to open cmd and run the SQL Server setup.exe with a configuration file.
ProcessStartInfo pStartInfo = new ProcessStartInfo();
pStartInfo.FileName = "cmd.exe";
pStartInfo.Arguments = "/c /q setup.exe /c /q /configurationFile=../configurationFile.ini";
pStartInfo.WorkingDirectory = installDir + #"\SQL Server Unpacked";
pStartInfo.CreateNoWindow = true;
pStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
pStartInfo.UseShellExecute = false;
pStartInfo.RedirectStandardInput = true;
pStartInfo.RedirectStandardOutput = true;
pStartInfo.RedirectStandardError = true;
Process p = new Process();
p.StartInfo = pStartInfo;
lb_SQLServerReadout.Text = "Please wait while the setup runs";
p.Start();
This is working alright. It'll attempt to install with the details of the configuration file, and if the configuration file contains invalid details then the setup.exe will give an error and not install.
I want to be able to get that error code and write it to a label on my form, so the user has some way of knowing that an error occurred and why it occurred. I considered using Process.StandardError.ReadToEnd, but it will always return null. I believe this is because the Process itself is cmd, not setup.exe (where the error actually occurs).
I've read that it's possible to get the last error code in cmd using echo %errorlabel%, and that does work when I run it manually, so I tried implementing it in my code:
p.StandardInput.WriteLine("echo %errorlevel%");
string s = p.StandardOutput.ReadLine();
p.WaitForExit();
I was hoping that s would be set to the output of the echo %errorlevel% input, but it is just set to null.
How can I get the error code of SQL Server setup, through my cmd Process?
Just as a side note, I've considered running setup.exe as the Process, but it requires elevation, which means enabling UseShellExecute, which in turn means disabling RedirectStandardError, which would prevent me getting the error code anyway.
That is all not necessary, the exit code of the "executable" invoked with cmd.exe /c will be the exit code of cmd.exe itself.
You can try this on the command line as well:
c:\> cmd.exe /c app.exe make-it-fail
c:\> echo %errorlevel%
The second line will print the exit code of "app.exe make-it-fail".
So, just read the value of the Process.ExitCode property, after Process.WaitForExit().
What particular values setup.exe (of SQL Server) sets in case it fails, I don't know. Should be something different than 0 though (by convention).

How to view Process.Start() Arguments as they are passed to executable

I'm trying to run a fortran executable with Process.Start and it is not working.
Process proc = new Process();
string args = "<C:\\file.in> C:\\file.out";
proc.StartInfo = new ProcessStartInfo(AppName, args);
proc.Start();
if I paste those arguments into a command window the application runs as expected. proc.Start() does not run as expected.
Any ideas how I can view what Start is actually passing as arguments? My gut feeling is that this is a quotes issue.
The executable launches and hangs, so I'm confident the AppName is getting passed in correctly, it looks like an argument problem.
I tried setting the WorkingDirectory to that of the input and output files as suggested in this question: process.start() arguments but that did not work.
Redirection with the < and > command line operators is a feature that's implemented by the command line processor. Which is cmd.exe. Use its /c argument to execute just a single command:
string args = "/c " + AppName + " < C:\\file.in > C:\\file.out";
proc.StartInfo = new ProcessStartInfo("cmd.exe", args);
proc.Start();
Your args string is exactly what is being passed as arguments to the executable. You can double check it reading your Process ProcessStartInfo.Arguments Property.
Something similar happened to me once, i.e., calling the executable from the command line worked and from code didn't, and it turned out that when called from the command line the executable was running on my PC's [C:] drive, and when called from code it was running on my PC's [E:] drive, which was full!
To check which directory your application is using to run the executable use the Directory.GetCurrentDirectory Method.

Categories

Resources