I am running a cmd.exe process from within a winforms application. However I can't seem to get the console window to run in the background (ie not show on screen)
here is my code
ProcessStartInfo si = new ProcessStartInfo("cmd.exe");
si.RedirectStandardInput = true;
si.RedirectStandardOutput = true;
si.UseShellExecute = false;
si.Arguments = "/c";
si.WindowStyle = ProcessWindowStyle.Hidden;
Process p = Process.Start(si);
Set CreateNoWindow to true.
si.CreateNoWindow = true;
si.CreateNoWindow = true;
si.WindowStyle = ProcessWindowStyle.Hidden;
Related
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();
I'm trying to use cmd CLI to excute a newman collection run. However when the process is running it's getting stuck and never finishes processing.
Any suggestions on how to deal with that?
string cmdCommand="newman run demo.postman_collection.json --env-var HTTP_PROXY --insecure";
int TotalTimeout= 150000;
CliProcess = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new
System.Diagnostics.ProcessStartInfo();
if (_inputDir != null)
{
startInfo.WorkingDirectory = _inputDir;
}
//startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = false;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C "+cmdCommand;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
bool processExited;
startInfo.RedirectStandardOutput = false;
CliProcess.StartInfo = startInfo;
CliProcess.Start();
CliProcess.StandardInput.WriteLine("exit");
//CliProcess.BeginOutputReadLine();
//CliProcess.BeginErrorReadLine();
//CliProcess.Close();
processExited = CliProcess.WaitForExit(TotalTimeout);
// //&& outputWaitHandle.WaitOne(TotalTimeout) && errorWaitHandle.WaitOne(TotalTimeout);
//CliProcess.CancelOutputRead();
//CliProcess.CancelErrorRead();
//ExitCode = GetProcessExitCode();
//CliProcess.Kill();
//}
//Wait additional minute for the process to exit
if (!processExited)
{
KillNewman();
TraceLogger.Instance.LogMessage(TraceLevel.Warning, MsgSrc, "[SendCmdCommand(string cmdCommand)] Newman process was killed due to timeout");
}
This is the most I can get out of it:
It gets stuck here^ and never continues.
the problem was due to the fact that the proxy was misconfigured so the request was sent trying to get to an unresponsive proxy server...
So in conclusion, there was nothing wrong with the code itself.
I'm running the below command from c#. There is a prompt that will be shown that I want to answer "yes" to how can I do this with the current code
If I run this as a batch script I can just do
echo y | pscp.exe -batch -pw password E:\\Certs\\client.conf me#<ip>:/home/user
which works - but unsure how I can replicate this using the below
string pscpPath="-batch -pw password E:\\Certs\\client.conf me#<ip>:/home/user";
ExecuteCopyCerts("pscp.exe", pscpPath);
Function:
public Boolean ExecuteCopyCerts(string fileName, string arguments)
{
txtLiveHubStatus.Text = "";
try
{
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo(fileName, arguments);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
return proc.ExitCode == 0;
}
}
Set RedirectStandardInput to true
procStartInfo.RedirectStandardInput = true
and then write to StandardInput
proc.StandardInput.WriteLine("yes");
To reiterate what Hesam said though the prompt is Y, not yes. This is the prompt for the cert, which only occurs on the first call to each new linux machine. I use this code today in one of our applications.
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "pscp";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = false;
psi.Arguments = $"-r -p -pw {passWord} \"{localFileNamePath}\" {userName}#{hostName}:{remotePath}";
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
using (Process process = new Process())
{
process.StartInfo = psi;
process.Start();
process.StandardInput.WriteLine("Y");
process.WaitForExit();
}
I'm starting a Process using a special User, Domain and Password. Although I told C# to hide the console window it is shown.
Here my code:
Process process = new Process();
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UserName = strUsername;
process.StartInfo.Domain = strDomain;
process.StartInfo.Password = secPassword;
process.StartInfo.FileName = "PsExec.exe";
process.StartInfo.Arguments = #"/accepteula -s \\" + strServername + #"program.exe";
process.Start();
process.WaitForExit();
I could find some hints in another forum:
If you call the Start(ProcessStartInfo) method with the
ProcessStartInfo..::.UserName and ProcessStartInfo..::.Password
properties set, the unmanaged CreateProcessWithLogonW function is
called, which starts the process in a new window even if the
CreateNoWindow property value is true or the WindowStyle property
value is Hidden.
Actually, I'm not really satisfied with this statement...
Thanks in advance.
Cheers
Alex
As i know there are workaround on this issue. You can launch hidden cmd with your params. Something like this:
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", String.Format("/accepteula -s \\{0}program.exe", strServername));
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
Process.Start(psi);
using (Process LMUTIL = new Process())
{
string arg1 ="argument"
LMUTIL.StartInfo.FileName = "program.exe";
LMUTIL.StartInfo.Arguments = arg1
LMUTIL.StartInfo.UseShellExecute = false;
LMUTIL.StartInfo.RedirectStandardOutput = true;
LMUTIL.StartInfo.CreateNoWindow = true;
LMUTIL.EnableRaisingEvents = true;
LMUTIL.OutputDataReceived += p_WriteData;
LMUTIL.Start();
LMUTIL.BeginOutputReadLine();
}
private void p_WriteData(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
Debug.WriteLine(e.Data.ToString());
}
}
I lifted this straight out of a project that does what you need. Subscribe to the p_WriteData event to capture what would appear in the command window.
After all, it is not possible to hide this psexec console window using the Process Class.
It's not necessary to use psexec. I used the WMI stuff instead:
ConnectionOptions remoteConnectionOptions = new ConnectionOptions();
remoteConnectionOptions.Impersonation = ImpersonationLevel.Impersonate;
remoteConnectionOptions.EnablePrivileges = true;
remoteConnectionOptions.Authentication = AuthenticationLevel.Packet;
remoteConnectionOptions.Username = strDomain + #"\" + strUsername;
remoteConnectionOptions.SecurePassword = secPassword;
ManagementScope scope = new ManagementScope(#"\\" + strServername + #"\root\CIMV2", remoteConnectionOptions); ManagementPath p = new ManagementPath("Win32_Process");
ManagementClass classInstance = new ManagementClass(scope, p, null); object[] theProcessToRun = { "myExecutable.exe" };
classInstance.InvokeMethod("Create", theProcessToRun);
How can I run a batch file from C# but in the backgound without the command prompt windows being displayed.
I use this Process.Start(batch.bat"); but this will display the command prompt.
Any idea?
Process p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
ProcessStartInfo si = new System.Diagnostics.ProcessStartInfo();
si.CreateNoWindow = true;
si.FileName = "setSecDLL.bat";
si.UseShellExecute = false;
System.Diagnostics.Process.Start(si);
You can specify that with a Startinfo:
var si = new System.Diagnostics.ProcessStartInfo();
si.CreateNoWindow = true;
si.FileName = "test.cmd";
System.Diagnostics.Process.Start( si);