Show the output of Powershell script in a WPF application - c#

I have a WPF application that executes a Powershell script and then displays a message in a textbox in the application. The Powershell script is executed like this:
string scriptPath = folderPath + "/EXECUTE.ps1";
string powershellPath = #"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
string outputLog = folderPath + "output.log";
bool is64 = IntPtr.Size == 8;
var ENV = "Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* "
+ (is64 ? ",HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*" : "")
+ " | Select-Object DisplayName";
ProcessStartInfo startInstall = new ProcessStartInfo(powershellPath, ENV);
startInstall.UseShellExecute = false;
startInstall.Arguments = scriptPath;
startInstall.EnvironmentVariables.Add("RedirectStandardOutput", "true");
startInstall.EnvironmentVariables.Add("RedirectStandardError", "true");
startInstall.EnvironmentVariables.Add("UseShellExecute", "false");
startInstall.EnvironmentVariables.Add("CreateNoWindow", "true");
Process Install = Process.Start(startInstall);
Install.Close();
Console.WriteLine("Script executed successfully");
Console.WriteLine("Output available at: " + outputLog);
The last two lines in Console.WriteLine are printed out in a textbox. I was wondering, is there a way that I can show the output of the Powershell terminal window inside of this textbox named txtboxExecutionResult? I am not executing any Powershell command from my application, just starting and executing the EXECUTE.ps1 file from the application. I'd really appreciate any help to point me in some direction.

I had a similar issue once with reading output from another application and I solved it by reading the standard output of the process.
Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = false;
process.StartInfo.CreateNoWindow = false;
process.StartInfo.FileName = "example.exe";
process.StartInfo.Arguments = args;
process.Start();
output = await process.StandardOutput.ReadToEndAsync();

Related

Create Angular build(ng build) from C#

So I need to make a Angular build (ng build --prod --aot-false) for a C# project(ashx page) with the Angular folder as a part of the project.
What I have tried right now is make a bat file inside the Angular folder outside the "src" folder as follows:
test.bat:
mkdir a
ng build --prod --aot=false
mkdir b
When I execute the commands the directories "a" & "b" are created instantly but the build is never made.
To execute the process I use:
filehandler.ashx:
System.Environment.CurrentDirectory =
context.Server.MapPath("~/ZipFiles/AngularProject_test/AngularProject/");
System.Diagnostics.Process.Start("test.bat");
This thread is a bit old but maybe this will help someone else. The following snippet will run ng build from C#:
// this will be the path to your app
var workingDirectory = #"C:apps\angular-hello-world";
// location of ng command
var command = #"C:\Users\Owner\AppData\Roaming\npm\ng.cmd";
// any arguments you want to pass to ng
var arguments = "build --prod --base-href /helloworld/ --output-path=prod";
var process = new Process();
var currentDirectory = Environment.CurrentDirectory;
try
{
Environment.CurrentDirectory = workingDirectory;
process.StartInfo.FileName = command;
process.StartInfo.Arguments = arguments;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WorkingDirectory = workingDirectory;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
// wait for the app to run and grab any output/errors generated
process.WaitForExit();
var output = process.StandardOutput.ReadToEnd();
var errors = process.StandardError.ReadToEnd();
Console.WriteLine("Output: " + output);
Console.WriteLine("Errors: " + errors);
}
finally
{
Environment.CurrentDirectory = currentDirectory;
}

Command line c# not working as intended

I have the following command that I wish to run (which works when I manually run it in cmd):
"C:\Program Files\APP\APP.exe" -CMV "C:\Program Files\APP\Second\IT" -ID 5 6 7 4 2
This is the code that I have written in C#:
string firstPath = #"""C:\Program Files\APP\APP.exe""";
string secondPath = #"""C:\Program Files\APP\Second\IT""";
string command = firstPath + " -CMV " + secondPath + " -ID 5 6 7 4 2");
I also tried the following piece of code:
int exitCode;
ProcessStartInfo processInfo;
Process process;
processInfo = new ProcessStartInfo("cmd.exe", command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
// *** Redirect the output ***
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
//processInfo.Arguments
process = Process.Start(processInfo);
process.WaitForExit();
// *** Read the streams ***
// Warning: This approach can lead to deadlocks, see Edit #2
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
exitCode = process.ExitCode;
Console.WriteLine("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
Console.WriteLine("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
Console.WriteLine("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
process.Close();
This still doesn't seem to work! Any help is much appreciated.
*********FINAL EDIT*********
This is the string that gets sent in as the command:
""C:\\Program Files\\DEEM\\DEEM.exe" -ENV "C:\\Program Files\\DEEM\\Environments\\IT" -ID 01004698001001 00285209090217 00285209090250 00285209090382 99041250643762"
Which results in the following error:
"'C:\Program' is not recognized as an internal or external
command,\r\noperable program or batch file.\r\n"
All I need to make it work is to take out the first and last quote which are wrapped due to the command being a string. I am not sure how to take the quotes out.
Your first example works if you wait for the process to exit:
static void Main(string[] args)
{
string firstPath = #"""C:\Program Files\APP\APP.exe""";
string secondPath = #"""C:\Program Files\APP\Second\IT""";
string command = firstPath + " -CMV " + secondPath + " -ID 5 6 7 4 2";
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
//startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = firstPath; //"cmd.exe";
startInfo.Arguments = command;
process.StartInfo = startInfo;
process.Start();
// **** don't forget to wait for the process to exit ***
process.WaitForExit();
var code = process.ExitCode;
var time = process.ExitTime;
}
In your second example you did use WaitForExit(), but there is some other stuff broken I did not investigate on.

C# Running batch file with arguments using UseShellExecute read the content instead executing it

I'm trying to run a batch file with arguments and also redirect the output.
When I don't redirect the output and use UseShellExecute = true, the batch file runs with the arguments as expected.
When I use UseShellExecute = false (to do the redirect), then I see that the command-line opens for a split a second and then closes.
I've read the output, using string output = proc.StandardOutput.ReadToEnd();
and I see that it contains the batch file content...
Can someone help me understand why it happens?
Thank you for your help :)
Here's the relevant code:
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.CreateNoWindow = false;
proc.EnableRaisingEvents = false;
// the command
proc.StartInfo.FileName = command;
// the parameters of the command
proc.StartInfo.Arguments = args;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
try
{
// in case there is missing '"'
if (isContainQuote && index < 0)
{
str = "missing '\"' in the command " + commandStr;
}
else
{
proc.Start();
string output = proc.StandardOutput.ReadToEnd();
if (bWaitForExit)
{
proc.WaitForExit(m_SHELL_CMD_TIMEOUT);
str = "Succeed to run the command: " + commandStr + ", Output: " + proc.StandardOutput.ReadToEnd();
}
else
{
str = "Succeed to run the command: " + commandStr;
}
}
}
catch (Exception e)
{
str = e.Message + ". Failed to run the command: " + commandStr;
// return the error from the operation system
}
Seeing your batch file could help. By default batch files echo their commands to standard out.
Try adding an #ECHO OFF command to the beginning of the batch file to be sure that the batch file commands aren't echoed to the standard output.

process.StandardOutput.ReadToEnd returns null

I have this code:
in c# windows form works right...but in asp.net its return null
var tempCadena = HttpContext.Current.Server.MapPath("~/" + HttpContext.Current.Session["db"] + "/" + "cadena");
System.IO.File.WriteAllText(tempCadena, cadena);
// Digestion SHA1
var tempSha = HttpContext.Current.Server.MapPath("~/" + HttpContext.Current.Session["db"] + "/" + "sha");
var opensslPath = HttpContext.Current.Server.MapPath("~/openssl/bin/openssl.exe");
Process process = new Process();
process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
process.StartInfo.FileName = opensslPath;
process.StartInfo.Arguments = "dgst -sha1 " + tempCadena;
process.StartInfo.UseShellExecute = false;
process.StartInfo.ErrorDialog = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
string codificado = "";
codificado = process.StandardOutput.ReadToEnd();
process.WaitForExit();
codificado = null I tried many things and nothing...can someone help me please?
I tried to change Process to ProcessStartInfo and doesn't work
I found it:
the: tempCadena has the value to the directory:
D:\ShamTec MySQL\
and it has a space in the folder name
that's why the process returns error
thanks

Execute command line using C#

All I am trying to do is send a command that opens a model with the program.exe
Supposed to be super simple!
Ex:
"C:\Program Files (x86)\River Logic\Enterprise Optimizer 7.4 Developer\EO74.exe" "C:\PauloXLS\Constraint Sets_1.cor"
The line above works well if pasted on the command prompt window.
However, when trying to pass the same exact string on my code it gets stuck on C:\Program
string EXE = "\"" + #tbx_base_exe.Text.Trim() + "\"";
string Model = "\"" + #mdl_path.Trim()+ "\"";
string ExeModel = EXE + " " + Model;
MessageBox.Show(ExeModel);
ExecuteCommand(ExeModel);
ExeModel is showing te following line on Visual Studio:
"\"C:\\Program Files (x86)\\River Logic\\Enterprise Optimizer 7.4 Developer\\EO74.exe\" \"C:\\PauloXLS\\Constraint Sets_1.cor\""
To me looks like it is the string I need to send in to the following method:
public int ExecuteCommand(string Command)
{
int ExitCode;
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + Command);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = true;
Process = Process.Start(ProcessInfo);
Process.WaitForExit();
ExitCode = Process.ExitCode;
Process.Close();
return ExitCode;
}
Things I've tried:
Pass only one command at a time (works as expected), but not an option since the model file will open with another version of the software.
Tried to Trim
Tried with # with \"
Can anyone see any obvious mistake? Thanks.
It's pretty straightforward. You just create a command line object then write to it, then to execute it you read back from it using SR.ReadToEnd():
private string GETCMD()
{
string tempGETCMD = null;
Process CMDprocess = new Process();
System.Diagnostics.ProcessStartInfo StartInfo = new System.Diagnostics.ProcessStartInfo();
StartInfo.FileName = "cmd"; //starts cmd window
StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
StartInfo.CreateNoWindow = true;
StartInfo.RedirectStandardInput = true;
StartInfo.RedirectStandardOutput = true;
StartInfo.UseShellExecute = false; //required to redirect
CMDprocess.StartInfo = StartInfo;
CMDprocess.Start();
System.IO.StreamReader SR = CMDprocess.StandardOutput;
System.IO.StreamWriter SW = CMDprocess.StandardInput;
SW.WriteLine("#echo on");
SW.WriteLine("cd\\"); //the command you wish to run.....
SW.WriteLine("cd C:\\Program Files");
//insert your other commands here
SW.WriteLine("exit"); //exits command prompt window
tempGETCMD = SR.ReadToEnd(); //returns results of the command window
SW.Close();
SR.Close();
return tempGETCMD;
}
Why are you opening a command prompt (cmd.exe)? Just pass the name of the executable.

Categories

Resources