I am attempting to run a windows command (e.g. whoami) without calling cmd.exe (or powershell) directly using C#.
Within VB this is possible using CreateObject(WScript.Shell) it obviously does not have to be the same method as within the VB, although that would be nice, but I just do not want to call cmd.exe directly.
How would I be able to achieve this?
This runs a console program, waits for exit and reads the output. I changed the cmd to ping since that takes longer and I can verify no console window opens.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "ping.exe";
startInfo.Arguments = "google.com";
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
// This wasn't needed
//startInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process processTemp = new Process();
processTemp.StartInfo = startInfo;
processTemp.EnableRaisingEvents = true;
try
{
processTemp.Start();
textBox1.Text = processTemp.StandardOutput.ReadToEnd();
processTemp.WaitForExit();
}
catch (Exception ex)
{
textBox1.Text = ex.Message;
}
You could call whoami.exe and capture the output directly.
The key is UseShellExecute = false to run the executable directly.
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = #$"{Environment.ExpandEnvironmentVariables("%systemroot%")}\system32\whoami.exe",
Arguments = // Put any command line arguments here
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
string line = proc.StandardOutput.ReadToEnd();
Related
I've been trying to create a simple application to backup my Windows Server databases aswell as a whole server backup.
For this I want to use batch files which are being executed by my application.
I tried several approaches but for some reason it always fails so I'd be happy if you could help me out.
Batch file BACKUPSERVER:
wbadmin start backup -backupTarget:D: -include:C: -allCritical -quiet
I have to run the bat as administrator or it fails due to missing permissions.
C# code:
static Task<int> RunProcessAsync(string fileName)
{
............
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.Verb = "runas";
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C \"D:\\SQLBACKUP\\BACKUPSERVER.bat\"";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
}
Debugging says 'wbadmin wasnt found'. 'runas' activated or not doesn't make any difference.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = fileName;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = true;
startInfo.CreateNoWindow = false;
// startInfo.Verb = "runas";
var process = new Process
{
StartInfo = { FileName = fileName },
EnableRaisingEvents = true
};
process.StartInfo = startInfo;
process.Exited += (sender, args) =>
{
tcs.SetResult(process.ExitCode);
process.Dispose();
};
process.Start();
Also doesn't work.
Any ideas?
EDIT:
I'm able to run commands like shutdown but wbadmin doesn't work whatsoever...
This is how I solved the problem:
Make sure ure compiling for 64bit if u intend to use your application on 64bit system, otherwise it will redirect to different subfolders and wont find 'wbadmin.exe'.
Run wbadmin with ProcessStart or run a batch but without direct cmd input, so use this with filename = batch file or wbadmin with startInfo.Arguments:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = fileName;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = true;
startInfo.CreateNoWindow = false;
// startInfo.Verb = "runas";
var process = new Process
{
StartInfo = { FileName = fileName },
EnableRaisingEvents = true
};
process.StartInfo = startInfo;
process.Exited += (sender, args) =>
{
tcs.SetResult(process.ExitCode);
process.Dispose();
};
process.Start();
Make sure u request administrator rights
Is it possible to redirect just stdin but also allow stdout to be written to the console?
I have a process which starts child processes and needs to read the output of those processes, but also display it in the console. Is it possible? I tried to just create my own console process but I can't write to it unless I UseShellExecute and the purpose is to show the output in the console.
protected void startp() {
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.Arguments = "/k";
//Can't redirect output without UseShellExecute = false
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = false;
p.StartInfo = psi;
p.Start();
//Can't write to StandardInput with UseShellExecute = true
p.StandardInput.WriteLine("#ECHO OFF");
p.StandardInput.WriteLine("echo | set /p=Child Process");
Console.ReadLine();
p.StandardInput.WriteLine("exit");
}
Running ChkDsk without redirecting StandardOutput works without an error like this:
var processStartInfo = new ProcessStartInfo(#"chkdsk.exe", "D:");
processStartInfo.UseShellExecute = false;
var process = Process.Start(processStartInfo);
process.WaitForExit();
if (process.ExitCode != 0)
throw new Exception("did not work");
When redirecting StandardOutput, the process ends with ExitCode 3.
var processStartInfo = new ProcessStartInfo(#"chkdsk.exe", "D:");
processStartInfo.RedirectStandardOutput = true;
processStartInfo.UseShellExecute = false;
var process = Process.Start(processStartInfo);
process.WaitForExit();
if (process.ExitCode != 0)
throw new Exception("did not work");
Doing the same thing with e.g. net use and redirected StandardOutput works without an error
var processStartInfo = new ProcessStartInfo(#"net ", "use");
Why? How can chkdsk be executed and StandardOutput be redirected?
Environment: Win 7 Pro x64, UAC disabled, Logged on as Administrator, Dot Net 4.0, VS 2012, WPF Application
I just ran this code with no problem and with an exit code of 0.
var cd = RunProcessDirect("chkdsk.exe", "c:", false);
protected ConsoleData RunProcessDirect(string processPath, string args,
bool isHidden)
{
Process process = SetupProcess(processPath, args, isHidden);
process.Start();
ConsoleData data = new ConsoleData();
data.StandardOutput = process.StandardOutput.ReadToEnd();
data.StandardError = process.StandardError.ReadToEnd();
data.ExitCode = process.ExitCode;
return data;
}
private Process SetupProcess(string processPath, string args,
bool isHidden)
{
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = isHidden
? ProcessWindowStyle.Hidden
: ProcessWindowStyle.Normal;
startInfo.CreateNoWindow = isHidden;
startInfo.FileName = processPath;
startInfo.Arguments = args;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
return process;
}
public class ConsoleData
{
public string StandardOutput { get; set; }
public string StandardError { get; set; }
public int ExitCode { get; set; }
}
cd.StandardOutput contained all the text output from the program, cd.StandardError was empty, and cd.ExitCode is 0.
Don't worry about the IsHidden stuff, that is just extra flair on my method that I didn't feel like taking off.
You must be running Visual Studio as Administrator and it will execute or you can add a application manifest file(add->new item->general->application manifest file) and changing this line <requestedExecutionLevel level="asInvoker" uiAccess="false" /> to this <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> which will just promp you to restart visual studio as administrator.
Simple answer, start a console process on non console application; if you would like to redirect standard output, please do a redirect standard input as well (even you are not using it).
So, just add below two lines in your code, it will work.
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardError = true;
This code works, runs chkdsk via cmd, and writes into log whole chkdsk output.
public int StartCheckDisc()
{
var process = new Process
{
StartInfo =
{
CreateNoWindow = false,
WindowStyle = ProcessWindowStyle.Normal,
FileName = "cmd",
Arguments = "/C chkdsk C:",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true
}
};
process.Start();
var output = process.StandardOutput.ReadToEnd();
var exitCode = process.ExitCode;
var errorCode = process.StandardError.ReadToEnd();
Log.Instance.Info(output);
Log.Instance.Info(exitCode);
Log.Instance.Info(errorCode);
process.WaitForExit();
return exitCode;
}
I'm using this code run in windows command prompt..
But I need this done programmatically using C# code
C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regiis.exe -pdf "connection
Strings" "C:\Users\XXX\Desktop\connection string\DNN"
try this
ExecuteCommand("Your command here");
call it using process
public void ExecuteCommand(string Command)
{
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + Command);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = true;
Process = Process.Start(ProcessInfo);
}
You may use the Process.Start method:
Process.Start(
#"C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe",
#"-pdf ""connection Strings"" ""C:\Users\XXX\Desktop\connection string\DNN"""
);
or if you want more control over the shell and be able to capture for example the standard output and error you could use the overload taking a ProcessStartInfo:
var psi = new ProcessStartInfo(#"C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe")
{
Arguments = #"-pdf ""connection Strings"" ""C:\Users\XXX\Desktop\connection string\DNN""",
UseShellExecute = false,
CreateNoWindow = true
};
Process.Start(psi);
You should be able to do that using a process
var proc = new Process();
proc.StartInfo.FileName = #"C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe ";
proc.StartInfo.Arguments = string.Format(#"{0} ""{1}""" ""{2}""","-pdf","connection Strings" ,"C:\Users\XXX\Desktop\connection string\DNN");
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
string outPut = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
var exitCode = proc.ExitCode;
proc.Close();
currently I have a process that runs, but it requires the user to enter
y <return>
<return>
The code I am using is as follows
ProcessStartInfo psi = new ProcessStartInfo();
string exepath = Directory.GetParent(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString();
Process proc = new Process();
psi.FileName = exepath + #"\lib\dnaml";
psi.RedirectStandardInput = true;
psi.Arguments = "y\r \r";
psi.UserShellExecute = true;
proc.StartInfo = psi;
proc.Start();
proc.WaitForExit();
I want to hard type these inputs in. Any suggestions? Thanks
The Arguments property corresponds to the command-line, not data entered via standard input.
The RedirectStandardInput property is part of the puzzle. Then you also need to write to the stream connected to the StandardInput property. Also note that standard input redirection is incompatible with ShellExecute, it needs CreateProcess to work. So set UseShellExecute = false.
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;
proc.StartInfo = psi;
proc.Start();
proc.StandardInput.WriteLine("y ");
proc.StandardInput.WriteLine();
proc.WaitForExit();