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

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.

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;"),

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 do I run a Python script from command line in a WPF application

I am trying to run a Python script from cmd line in a WPF application. I have this code which opens cmd line to the correct directory:
string cmd = #"webplus_builder.py";
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.WorkingDirectory = #"C:\Temp\WebBuilder";
p.StartInfo.Arguments = string.Format("{0} {1} {2}", cmd, "WAF", _CountryCode);
p.StartInfo.UseShellExecute = false;
p.Start();
I now want to run webplus_builder.py from that directory like so:
How do I achieve this? Is it a case of just adding arguments to my Process as I've attempted to do?
You cannot execute python scripts directly, it's python itself that has to be run: Use the name of your script as the first parameter to it, the following parameters are passed to your script.
(Windows handles a double click on py-files by "opening them with" python - exactly as described).
Read the official docs for details:
1. Command line and environment — Python 2.7.9 documentation
1. Command line and environment — Python 3.3.6 documentation

Process.Start cmd results in "is not recognized"

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.

Run bat file in c# throws not recognized error

I wan to add some DNS records in c# program via a bat file so I have written these lines in bat file:
set servername=%1
set siteaddress=%2
"C:\Windows\System32\dnscmd.exe" %servername% /zoneadd %siteaddress% /primary /file %siteaddress%.dns
and I have written these lines in C#:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.WorkingDirectory = Application.StartupPath;
p.StartInfo.FileName = General.DnsBatPath;
p.StartInfo.Arguments = string.Format("{0} {1}", General.DnsServerName, txtSiteAddress.Text);
p.Start();
p.WaitForExit();
I get this error "dnscmd.exe is not recognized as internal or external command..." but when I run bat file manually (outside of C#) all things are OK.
I changed my C# code to check what happened
Process.Start(#"C:\Windows\System32\dnscmd.exe");
I still get "not recognized ..." error.but I can see dnscmd.exe in "C:\Windows\System32".
I changed my C# code again to check another thing:
Process.Start(#"C:\Windows\System32\cmd.exe");
and after that CMD windows will be opened???
any idea?
In answer to your second question, you can always check the environmental variable PROCESSOR_ARCHITECTURE to see if it contains the number 64.
set servername=%1
set siteaddress=%2
if "%PROCESSOR_ARCHITECTURE%" equ "%PROCESSOR_ARCHITECTURE:64=%" (
REM 32bit
"C:\Windows\System32\dnscmd.exe" %servername% /zoneadd %siteaddress% /primary /file %siteaddress%.dns
) else (
REM 64bit
"%windir%\Sysnative\dnscmd.exe" %servername% /zoneadd %siteaddress% /primary /file %siteaddress%.dns
)
Possibly a more reliable method is to get it from the registry:
set servername=%1
set siteaddress=%2
for /f "tokens=3" %%x in ('reg Query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier') do (
set arch=%%x
)
if %!arch:~-2!%==64 (
set dnsPath=%windir%\Sysnative
) else (
SET dnsPath=C:\Windows\System32
)
"%dnsPath%\dnscmd.exe" %servername% /zoneadd %siteaddress% /primary /file %siteaddress%.dns
In my case I created a console application to run a batch file with some java command but was getting 'java' not recognized as an internal command error.
Took me few hours but the solution is straight forward. My server had JVM running on 64 bit so I changed the platform target to 64 bit.
x86 is 32 bit and x64 is 64 bit. Project properties are below:
Try this code:
ProcessInfo psi= new ProcessStartInfo("cmd.exe", string.Format("/c {0} {1} {2}", General.DnsBatPath, General.DnsServerName, txtSiteAddress.Text);
psi.UseShellExecute = false;
process = Process.Start(psi);
process.WaitForExit();
The /c parameter says that the given command should run and then cmd.exe should exit. For details, run cmd /? in windows console.
You can also try what happens when you set ShellExecute to true. Then the process should start the same way like a file is double-clicked in explorer. The disadvantage of shell execution is that if the user changed the .BAT file default application to (for example ) notepad, the file will not be executed but opened in notepad.
If you also want to redirect the console output, look here: Executing Batch File in C#

Categories

Resources