Process class db2cmd c# - 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";

Related

WPF Run CMD line with simple argument, print output - without batch file

I'm having some difficulty doing this without using a batch file. What I want to do is when a button is clicked, run the command line with a simple argument that I specify.
Here's my code so far:
ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe");
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.UseShellExecute = true;
startInfo.Arguments = "dir";
Process.Start(startInfo);
string output = Process.StandardOutput.ReadToEnd();
txtblkOutput.Text = output;
However, this just opens a cmd window and nothing happens. The text box remains blank.
However I can do this:
var process = new Process();
process.StartInfo.FileName = "C:/Users/user/Documents/SUB-20 Tool/commands.bat";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
string output = process.StandardOutput.ReadToEnd();
txtblkOutput.Text = output;
Inside the batch file it just says dir. And this works, I get the output sent to my textbox.
Why does this work only with a batch file? Can I do this without it, with just using the argument property?
This is the excepted behaviour. When you execute cmd.exe with the argument dir, it does not execute the command.
As an exemple, see the screenshot below :
The correct way to execute a command in the arguments is the following :
cmd.exe /C <command>

msinfo32.exe can't collect information on a sharepoint page ASP.net

I am creating a new process on my Sharepoint web application. I've run the same command as below and works on my OS but not on my web app. I wanted to know why and if this is even possible. Here's code that creates the process.
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"report.txt");
Process proc = new Process();
proc.EnableRaisingEvents = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.FileName = "msinfo32.exe";
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.Arguments = "/report " + filePath;
proc.Start();
proc.WaitForExit();
proc.Close();
It creates a file with every filed as Can't collect information, example:
Can't Collect Information
[Hardware Resources]
[Conflicts/Sharing]
Can't Collect Information
[DMA]
Am I doing it wrong, are there settings to enable on sharepoint in order to run msinfo32?
WMI is enabled on my OS.
Found the answer. Sharepoint requires an elevated security state to run this command. Wrapping the code in this helped run msinfo32.exe. Thanks to Amal Hashim and Method Man for recommending this
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//Your code goes here
});
I went to the directory where my debug folder is running a console app on my side
here is what I did and it work..
change the name of your Report.txt to out.log open the out.log file and just type anything in it.. save it and close it .. and run the following code below and you will se the SystemInformation window pop up. add this in the Page_Load event to test it
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "out.log");
Process proc = new Process();
proc.EnableRaisingEvents = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.FileName = "msinfo32.exe";
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.Arguments = "/out " + filePath;
proc.Start();
proc.WaitForExit();
proc.Close();
I just tested this from my Page_Load in my web page and it works like a charm.. what you need to add to the header of the webpage that you are launching it from is the following
using System.Diagnostics;
using System.IO;

How to read message from batch file from C# application

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)

Check if SCHTASKS file exists

I am making a backup program in c# in which I use a .bat script to create a new Tasks that runs my program on an interval. I need to make sure the .bat is only run if the task does not exist. To do this I use the following piece of code, but it doesn't seem to detect whether or not it exists.
if (!File.Exists(#"C:\Windows\System32\Tasks\BackupUtil.*"))
{
Process proc = new Process();
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.FileName = #"C:\Users\Sebastian Esp\documents\visual studio 2012\Projects\FileBackUp_Sorter\FileBackUp_Sorter\Task_Schedule.bat";
proc.Start();
proc.WaitForExit();
}
Use Directory.GetFiles instead
if (Directory.GetFiles(#"C:\Windows\System32\Tasks", "BackupUtil.*").Length == 0)
//....Your code
}
http://msdn.microsoft.com/en-us/library/wz42302f(v=vs.110).aspx

Executing "java -version" programmatically places the output in StandardError instead of StandardOutput

I am facing very strange behavior as I am trying to programmatically detect the java version on my PC. I am using the following C# code:
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c java -version");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
// Get the output into a string
output = proc.StandardOutput.ReadToEnd();
if (output == "")
output = proc.StandardError.ReadToEnd();
return output;
This displays the correct information but the result is found in proc.StandardError.ReadToEnd() instead of proc.StandardOutput.ReadToEnd() as in any other command (i.e. 'java -help').
Even more weird, if I run "java -showversion" which should output both java version and then help information I get the help info in the StandardOutput and the version info is in the StandardError.
This doesn't make sense to me.
I tested this on 2 Windows 7 x64 machines and 1 XP x32. Same thing everywhere. It's really weird.
Looks likes this (i.e. version being printed on standard out) is an old issue that sun (oracle) has never fixed in order to avoid breaking legacy systems: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4380614. On linux, java -version > foo will create an empty file while java -version 2> foo will create a file containing the version.
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c java -version");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.EnableRaisingEvents = true;
// create event and wait for data receive
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
proc.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived);
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
static void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
string s = e.Data;
}
static void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
string s = e.Data;
}
This should do the trick:
java -version 2>&1 | more
"more" is not required, unless you want to redirect it to file for example.
Works both on *NIX and Win.

Categories