How to read message from batch file from C# application - c#

I have a batch file that copy file from one folder to another folder. So I would like to run this file from a C# windows services then I would like to read if the script generate an error or it works correctly.
This is my code for lunch it but I don't Know how to read the message of the script:
SCRIPT CODE:
REM
REM This script moves files with results from GOLD server and saves them on MES06 server on .
REM IMPORT folder.
REM
REM Robocopy Options:
REM /R:2 Two retries on failed copies (default is 1 million)
REM /W:5 Wait 5 seconds between retries (default is 30 sec).
REM
REM GOLD QAS Inbound Folder: \\goldqas01.app.pmi\limscihome$\RootDirectory
REM
for /f "delims=: tokens=2,3" %%j in (F:\MES2GOLD\copy_list_test.txt) do ROBOCOPY.EXE %%j %%j\..\BACKUP *.* /R:2 /W:5 /log+:%%j\..\LOGS\MES2GOLD.log & ROBOCOPY.EXE %%j %%k *.* /R:2 /W:5 /MOV /log+:%%j\..\LOGS\MES2GOLD.log
PAUSE
C# Code:
public void execute(string workingDirectory, string command)
{
// create the ProcessStartInfo using "cmd" as the program to be run, and "/c " as the parameters.
// Incidentally, /c tells cmd that we want it to execute the command that follows, and then exit.
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", #"/c C:\Users\mcastrio\Desktop\GOLD2MES.bat");
procStartInfo.WorkingDirectory = workingDirectory;
//This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
//This means that it will be redirected to the Process.StandardError StreamReader. (same as StdOutput)
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
//This is importend, else some Events will not fire!
proc.EnableRaisingEvents = true;
// passing the Startinfo to the process
proc.StartInfo = procStartInfo;
// The given Funktion will be raised if the Process wants to print an output to consol
proc.OutputDataReceived += DoSomething;
// Std Error
proc.ErrorDataReceived += DoSomethingHorrible;
// If Batch File is finished this Event will be raised
proc.Exited += Exited;
}
Can we help me?

You can use the code below inside your loop:
var startInfo = p.StartInfo;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = false;
startInfo.StandardOutputEncoding = Encoding.GetEncoding("ibm850");
startInfo.RedirectStandardOutput = true;
startInfo.FileName = filebatch;
startInfo.Arguments = arguments;
p.Start();
var output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Or just use ProcessHelper.Run from TestSharp library:
ProcessHelper.Run(string exePath, string arguments = "", bool waitForExit = true)

Related

Unable to start a command line with spaces from C#

The command line I need to execute is
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe" /Run "C:\unity\unity\MRTK Tutorial\Builds\MRTK Tutorial.sln"
This works from a windows command line without issues,
I formatted it into a string for visual studio
When running from C# this command never executes and the contents of result are ""
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("C:\\Program Files(x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\IDE\\devenv.exe", " /Run \"C:\\unity\\unity\\MRTK Tutorial\\Builds\\MRTK Tutorial.sln\"");
// The following commands are needed to redirect the standard output.
// This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
You can try the following code to use c# to execute devenv.exe.
var devEnvPath = #"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe";
string SolutionFile = #"D:\Test\testconsole\testconsole.sln";
ProcessStartInfo startInfo = new ProcessStartInfo(devEnvPath);
startInfo.Arguments = "/Run " + SolutionFile;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
Console.ReadKey();
Based on my test, the above code will open vs2019 and open the startup project.

c# run .bat file application as administrator do not start

I have to run a .bat file from c#...
I use this method.
file = "C:\\Diego\\PublishCore\\Startup_service.bat";
ProcessStartInfo psi = new ProcessStartInfo();
psi.CreateNoWindow = true;
psi.FileName = file;
psi.UseShellExecute = true;
psi.Verb = "runas";
Process.Start(psi);
.BAT is executed... but the action I ask to perfom it does not execute...
If my .bat says MKDir MyDir... Its creates a Directory called MyDIr with no problems.
But when my bat says dotnet myApp.dll, a cmd Windows opens and closes, but it does not start myApp aplication....
If a doublé-click my .bat is runs fine.
What I am missing? Why the aplication does not start?
I solved it...
The problem was that, as my bat run the instruction dotnet myApp.dll.
I set the path file where the file was, but it was executed in the location where the my Solution is, instead of running in the same directory where I have .bat file.
I have to set WorkingDirectory and Arguments
C:\\Diego\\PublishCore\\Startup_InomCore.bat
ProcessStartInfo psi = new ProcessStartInfo();
psi.WorkingDirectory = "C:\\Diego\\PublishCore";
// psi.CreateNoWindow = true;
psi.FileName = #"cmd.exe";
psi.Arguments = "/c start /wait " + "C:\\Diego\\PublishCore\\Startup_InomCore.bat";
// psi.UseShellExecute = true;
psi.Verb = "runas";
var process = Process.Start(psi);

C# process can not execute batch file (contain timeout command) correctly

I'd like to execute a batch file without showing terminal window
and I need to get the standard output contents.
Here is the batch file:
timeout /T 5
exit 0
Below is my partial C# code:
static void Main(string[] args)
{
bool ShowTerminal = true;
Process proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
string ExecContent = "\"" + args[0] + "\"";
proc.StartInfo.Arguments = "/c " + ExecContent;
proc.StartInfo.UseShellExecute = ShowTerminal;
proc.StartInfo.RedirectStandardError = !ShowTerminal;
proc.StartInfo.RedirectStandardInput = !ShowTerminal;
proc.StartInfo.RedirectStandardOutput = !ShowTerminal;
proc.Start();
proc.WaitForExit();
}
I found that variable ShowTerminal set true, then everything is going well
except I can not get standard output contents
But if variable ShowTerminal set false, timeout command will be skipped
Is there any solution for this problem? Thanks!
If you specify "redirect" options you should also provide their redirection streams (STDIN, STDOUT) and ensure they are being emptied/read/processed as CMD would expect.
Chances are good that 'timeout' is failing to detect any STDIN/STDOUT and therefore performs a noop.

Process class db2cmd c#

I have my program which needs to run a ".BAT" file in IBM DB2 (db2cmd.exe). And log the contents of that console into a string, which I should be able to format.
Status quo is:
The bat file contains username and password to the database, Export to csv query. The bat file when executed manually works absolutely fine.
The problem is that I am not able to capture the details of that console into a string.
Code snippet is as follows:
proc.StartInfo.FileName = "db2cmd.exe";
proc.StartInfo.Arguments = #"C:\test.bat";
proc.StartInfo.WorkingDirectory = #"C:\Program Files\IBM\SQLLIB\BIN\";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.OutputDataReceived += (o, e) => s.AppendLine(e.Data);
proc.ErrorDataReceived += (o, e) => s.AppendLine(e.Data);
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
code = proc.ExitCode;
db2cmd.exe opens a new command shell by default. Try using the command switches /i /c to run your script in the same shell.
Using -i option with db2cmd.exe should fix this issue. Modify first line of your program as below:
proc.StartInfo.FileName = "db2cmd.exe -i";

How I can execute a Batch Command in C# directly?

I want to execute a batch command and save the output in a string, but I can only execute the file and am not able to save the content in a string.
Batch file:
#echo off
"C:\lmxendutil.exe" -licstatxml -host serv005 -port
6200>C:\Temp\HW_Lic_XML.xml notepad C:\Temp\HW_Lic_XML.xml
C# code:
private void btnShowLicstate_Click(object sender, EventArgs e)
{
string command = "'C:\\lmxendutil.exe' -licstatxml -host lwserv005 -port 6200";
txtOutput.Text = ExecuteCommand(command);
}
static string ExecuteCommand(string command)
{
int exitCode;
ProcessStartInfo processInfo;
Process process;
processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
// *** Redirect the output ***
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
process = Process.Start(processInfo);
process.WaitForExit();
// *** Read the streams ***
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
exitCode = process.ExitCode;
process.Close();
return output;
}
I want the output in a string and do this directly in C# without a batch file, is this possible?
Don't need to use "CMD.exe" for execute a commandline application or retreive the output, you can use "lmxendutil.exe" directly.
Try this:
processInfo = new ProcessStartInfo();
processInfo.FileName = "C:\\lmxendutil.exe";
processInfo.Arguments = "-licstatxml -host serv005 -port 6200";
//etc...
Do your modifications to use "command" there.
I hope this helps.
It doesn't look to me like your batch file will produce any output. If you run it in the command line, do you see an output? You have the redirection > operator in your bat file line, so it seems like you're sending output to the xml file.
If you have saved the output to an xml file, maybe you should just load that using C# once your process exits.

Categories