I'm currently solving a problem of starting external tool from .net app.
I have this part of code:
proc.StartInfo = new ProcessStartInfo(_app, _args);
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
But, after starting application I get an error to StandartError output witn promt confirmation answer "enter y/n".
I've already tried to input "y" via standart input, right after starting process, but still get the same error.
var standartInput = proc.StandardInput;
standartInput.AutoFlush = true;
standartInput.WriteLine("y");
standartInput.Close();
I'd really appreciate any help. Thanks.
PS: PuTTY Secure Copy client - is the external app I'm using from code. There is a confirmation promt, when running app for first time to save servers fingerprint in system registry.
The code looks OK to me. Maybe you need to sleep for a second or something before writing the "y". I would imagine that the program takes a little while to ask the user for input
Related
I'm trying to start tomcat from my c# wpf app using the startup.bat and after deploying the war files, I want to close it. Here is how I've been doing it and it seemed to work fine.
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = Tomcat_DIR_tbox.Text + #"\bin\startup.bat";
proc.StartInfo.WorkingDirectory = Tomcat_DIR_tbox.Text + #"\bin\";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
// do some bla bla
//Close Tomcat
proc.StartInfo.Filename = Tomcat_DIR_tbox.Text + #"\bin\shutdown.bat";
proc.Start();
proc.WaitForExit();
Now I've been thinking that although it works, it's not quite right ? the Tomcat application started never stops unless I tell it to, it feels wrong to use the same process to also shut it down ?
What I've down now is something like this : Kept the process for starting up tomcat, and created another one which calls for the shutdown:
//Close tomcat
System.Diagnostics.Process proc_shutdown = new System.Diagnostics.Process();
proc_shutdown.StartInfo.WorkingDirectory = Tomcat_DIR_tbox.Text + #"\bin\";
proc_shutdown.StartInfo.FileName = Tomcat_DIR_tbox.Text + #"\bin\shutdown.bat";
proc_shutdown.StartInfo.CreateNoWindow = true;
proc_shutdown.Start();
proc_shutdown.WaitForExit();
The only thing I don't like about this method is that it brings a message which asks me if I allow the shutdown.bat to be called from my application, which I can uncheck "Don't ask me again for this file" but I still don't like the user experience it provides.
I also tried calling directly proc.Close() instead of doing proc.Filename = path_to_shutdown and proc.Start(), but it seemed to hang up my application and never close tomcat.
So what is the best way to start tomcat, do some stuff and then close it up ? Thanks , Razvan.
Based on my observation, what you are doing is fine to start and stop the tomcat server from WPF application. But, if you want to hide the security warning, Then Open Internet Explorer Go to Tools -> Internet Options and then select "security" tab from there select (Custom level..).. In that in the Miscellaneous group there will be option called
"Launching Applications and Unsafe files" -> Select Enable Radio button. Then it won't show you the "allow the shutdown.bat" popup.
Hope, it helps.
I can find a lot of threads discussing Process.Start but none which sound like mine. The code below has been working for years on Windows Server 2003 & 2008. I'm now trying to install the same application on 2012 but although "My.exe" starts, Process.Start itself hangs - so "Started" is never logged. Can anybody suggest what the issue might be?
Many thanks in advance,
Michael
ProcessStartInfo psi = new ProcessStartInfo("C:\\My.exe");
psi.UseShellExecute = false;
psi.LoadUserProfile = false;
psi.WindowStyle = ProcessWindowStyle.Normal;
psi.ErrorDialog = false;
if (Environment.OSVersion.Version.Major >= 6) psi.Verb = "runas";
psi.Arguments = "\"MyArgs\"";
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
_logger.Info("Starting");
_process = Process.Start(psi);
_logger.Info("Started");
Possibly the same thing as this?
Also assuming that
"C:\My.exe"
is a typo = "C:\\My.exe" or #"C:\My.exe"
I believe that the "runas" verb to interactively demand administrative permissions only works when ProcessStartInfo.UseShellExecute=true, assuming that the app does run interactively and you want the use to be prompted to approve an adminstrative action. If not you might look into demanding the permissions from a manifest.
Have you tried wrapping your _process = Process.Start(psi) in a try/catch and logging any exceptions?
Have you tried dropping this code into a console app with both of the RedirectStandard ... to false to see what happens?
I am trying to write a C# program that is supposed to call the runas tool from windows and input the password automatically.
What I tried:
Process runas = new Process();
runas.StartInfo.FileName = "runas";
runas.StartInfo.UseShellExecute = false;
runas.StartInfo.RedirectStandardInput = true;
runas.StartInfo.Arguments = "\"/user:domain\\username\" \"cmd.exe\"";
runas.Start();
StreamWriter stream = runas.StandardInput;
stream.WriteLine("our super secret password");
stream.Flush();
stream.Close();
runas.WaitForExit();
runas.Close();
What happended:
I get the following output.
Please enter the password for "...":
Trying to execute cmd.exe as user "kfz\dummy"...
RUNAS-ERROR: cmd.exe could not be executed
1326: Authentication failed: unknown username or password.
(translated by me from my german windows)
Yes, I quadrupel checked the password and username. Entering everything by hand in the command line works fine.
What I experimented with:
I tried redirecting the Output as well and reading from it, no success.
I tried different variants of writing to the stream:
stream.Write("our super secret password");
stream.Write("our super secret password\n");
stream.Write("our super secret password\r\n");
All results in the same behaviour.
What I noticed:
The runas process seems not to wait for me to write to the stream.
I added a Sleep before writing and I immediately got the above output.
I am afraid runas uses some nonstd-input.....
Research result:
Upon trying to find out what kind of input runas uses I was not successfull.
I found an alternative to the windows builtin runas here however I would prefer not to use it although I might fall back to it if it is impossible to do.
EDIT:
Ok I found sources that say microsoft deliberately prevented people from doing that.....
I hate it when someone does that! If I WANT to use something that is not secure then who is microsoft to keep me from that!
Sorry I got off topic.
One question remains... Can we still get around it somehow? Can we hack runas? ;)
The whole reason why you're not supposed to do that is because there's an API for that.
No need to use runas.
ProcessStartInfo lets you specify the UserName and Password directly.
For example:
var psi = new ProcessStartInfo();
psi.Domain = "YourDomain";
psi.UserName = "YourUserName";
psi.Password = securePassword;
psi.FileName = "cmd.exe";
Process.Start(psi);
i am building a GUI over an console application that i use, i'm trying to use C# Process and RedirectStandardInput/Error/Output.
The problem is when i redirect anything the console applications stops printing data, i've redirected only stdin and watched the console application window itself, nothing, i've redirected stdin, out and err and no data is received by my program.
This is the only application i tested that doesn't work with Std redirection, is it an implementation issue?
Code:
fmproc = new Process();
fmproc.StartInfo.FileName = #"fm.exe";
fmproc.StartInfo.Arguments = "";
fmproc.StartInfo.UseShellExecute = false;
fmproc.StartInfo.CreateNoWindow = false;
fmproc.StartInfo.RedirectStandardInput = true;
fmproc.StartInfo.RedirectStandardError = true;
fmproc.StartInfo.RedirectStandardOutput = true;
fmproc.Start();
fmproc.StandardOutput.ReadLine();
Perhaps you could try:
fmproc.StandardOutput.ReadToEnd();
fmproc.WaitForExit();
Rather than the ReadLine(); Of course you might want to do something more interesting with the output string - but I'm just following your example code.
Our C# (V3.5) application needs to call another C++ executable which is from another company. we need to pass a raw data file name to it, it will process that raw data (about 7MB) file and generate 16 result files (about 124K for each).
The code to call that executable is this:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = exePath;
startInfo.Arguments = rawDataFileName;
try
{
Process correctionProcess = Process.Start(startInfo);
correctionProcess.WaitForExit();
}
catch(nvalidOperationException ex)
{
....
}
catch(...)
...
It works fine. Now we have new raw data. After replace the old raw data with the new raw data file. That executable process never return to us. It will hang forever. If we kill our C# application, those result files will be generated in the target directoy. It looks like the executable does create those result files but has issue to write to the disk and return to us until the process is terminated.
It is NOT like this with the old raw data file.
When we run the executable with the new raw data directly (no from our C# app call), it works fine. This means this executable has no problem with the new raw data.
My question 1: what's the possible causes for this behaviour?
Now I change our code with startInfo.UseShellExecute = true; and add startInfo.WorkingDirectory= ..., and disabled
//startInfo.RedirectStandardError = true;
//startInfo.RedirectStandardOutput = true;
Then it works.
My question 2: why use Windows Shell solve this issue?
My question 3: why it works before without using Shell?
My question 4: when we should use Shell and When shouldn't?
thanks,
Several possibilities:
You are redirecting output and error but not reading it. The process will stall when its stdout or stderr buffer fills up to capacity.
The program might be displaying an error message and waiting for a keypress. You are not redirecting input nor check stderr, that keypress will never come.
Some programs, xcopy.exe is a very good example, require stdin to be redirected when you redirect stdout. Although the failure mode for xcopy.exe is an immediate exit without any diagnostic.
Seeing it fixed when you kill your C# program makes the first bullet the likeliest reason.
I know this, it is a very common problem. I has to do with the output, which must be handled asynchronously. You just can't WaitForExit when output exceeds certain amount of data.
You need to add
myStdErr= correctionProcess.StandardError.ReadToEnd();
Only once usually works, if you want to overkill this works ("P" being my Process)
while (!P.HasExited)
stdErr+= P.StandardError.ReadToEnd();
If you don't need the stdout/stderr, just turn the Redirect* properties to false.