I am trying to restart iis remotely (Windows Servr 2012) from my local machine (Windows 7). The below command in command line doesn't work to restart IIS;
iisreset servername /restart
but the below command works fine when I tried in command line.
psexec iisreset \\servername /restart
Now the issue is when I try with below code in C#,
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "\C psexec iisreset \\servername /restart";
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
// capture what is generated in command prompt
var output = process.StandardOutput.ReadToEnd();
If I give any other arguments in the above code like 'ipconfig', it gives me the expected output. But when I try with psexec, it gives empty output. But it works well when tried in command prompt.
I have also tried by using 'psexec.exe' in the filename and by removing '\C psexec' in the arguments. But still no luck.
Could you please anyone help me to resolve this?
Thanks in Advance.
I have found that when using PSexec like this that you Shouldn't use CMD.exe, and you need to ensure that you have the full path to psexec. Even if it is in the same directory as your application exe.
//Assume that psexec.exe is in same location as application
//Get directory of running applications
String AppPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).Replace("file:\\","");
//Set up start infor details
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = false;
//Combine path of running app
startInfo.FileName = Path.Combine(AppPath, "psexec.exe");
startInfo.Arguments = "\\servername c:\path\to\iisreset /restart";
//Execute
Process nProc = Process.Start(startInfo);
nProc.Start();
I hope u need to provide the domain admin credentials to it.
private int ExcecuteCommand(string command, string fileName, bool getResult, string timeout = null)
{
try
{
var secure = new SecureString();
foreach (char c in txtAdminPassword.Text)
{
secure.AppendChar(c);
}
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
pProcess.StartInfo.Domain = txtDomainName.Text;
pProcess.StartInfo.UserName = txtUser.Text;
pProcess.StartInfo.Password = secure;
pProcess.StartInfo.FileName = fileName;// AppDomain.CurrentDomain.BaseDirectory + #"PSTools\PsExec.exe"; ;
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -i -s -accepteula ipconfig /all", ipAddress);
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -accepteula netstat -ano",ipAddress);
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -accepteula -i CheckURLConnectivity", ipAddress);
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -accepteula ping {2}", ipAddress, AppDomain.CurrentDomain.BaseDirectory + #"Installer\CheckURLConnectivity.exe","10.10.10.35");
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -accepteula cmd /c type C:\ServiceLog.txt", ipAddress);
pProcess.StartInfo.Arguments = command;//string.Format(#"\\{0} -accepteula -c -f {1}", compName, AppDomain.CurrentDomain.BaseDirectory + #"Installer\CheckURLConnectivity.exe");
pProcess.StartInfo.UseShellExecute = false;
Process.StartInfo.RedirectStandardInput = true;
pProcess.StartInfo.RedirectStandardOutput = true;
pProcess.StartInfo.RedirectStandardError = true;
pProcess.StartInfo.CreateNoWindow = true;
logger.log("Query " + command);
pProcess.Start();
if (timeout == null)
pProcess.WaitForExit();
else
pProcess.WaitForExit(Convert.ToInt32(timeout));
string strOutput = string.Empty;
if (pProcess.HasExited == true && pProcess.ExitCode != 0)
{
string _errorMessage = GetWin32ErrorMessage(pProcess.ExitCode);
pProcess.Kill();
return pProcess.ExitCode;
}
else
return 0;
}
catch (Exception)
{
return -1;
}
}
IISreset requires elevated privilege to work.So you have to use the -h switch with psexec
-h If the target system is Vista or higher, has the process run with the account's elevated token, if available.
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "psexec.exe";
startInfo.Arguments = "-h iisreset \\servername /restart";
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
// capture what is generated in command prompt
var output = process.StandardOutput.ReadToEnd();
Thank you all for your valuable response. It works fine with below code :)
startInfo.FileName = #"C:\Windows\Sysnative\PsExec.exe";
startInfo.Arguments = "iisreset \\servername /restart";
Reference: Process.Start in C# The system cannot find the file specified error
I am trying to install a network printer on a non-domain machine.
I found the only way to prompt Windows Security to allow authentication to install the printer and run the exe on the shared drive to be by using Start \\PAPERCUT\FollowMe in CMD but when converting it to a C# winform, it does not install.
I am prompted to authenticate the connection to the server and the exe runs, but the printer does not install and does not throw any errors.
Ping pingSender = new Ping();
IPAddress address = IPAddress.Loopback;
PingReply reply = pingSender.Send("192.168.137.37");
if (reply.Status == IPStatus.Success)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = #"/C Start \\PAPERCUT\FollowMe";
startInfo.Arguments = #"/C rundll32 printui.dll PrintUIEntry /in /n \\PAPERCUT\FollowMe";
startInfo.Arguments = #"/C rundll32 printui.dll PrintUIEntry /y /n \\PAPERCUT\FollowMe";
startInfo.Arguments = #"/C Start \\PAPERCUT\PCClient\win\pc-client.exe";
process.StartInfo = startInfo;
process.Start();
greenConnectionLabel.Visible = true;
redConnectionLabel.Visible = false;
}
else
{
greenConnectionLabel.Visible = false;
redConnectionLabel.Visible = true;
}
}
I sort of stuck into what should be a small issue. I need to run two different processes but the second failures.
My first process is:
string workingDirectory = "c:\\xxxx\\bin\\";
string fileName = "xxxx.xxxx.cmd";
string arguments = "-Sxxxx -f -d --port xxxx > c:\\xxxx\\tmp\\bug.log 2>&1";
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = workingDirectory;
startInfo.FileName = fileName;
startInfo.Arguments = arguments;
Process process = new Process();
process.StartInfo = startInfo;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
No worries here. Everything works but the second.
string workingDirectory = "c:\\xxxx\\bin\\";
string fileName = "WebDaemon.exe";
string arguments = "-debug -i WebDaemon.xxxx.1234 --ServerPort=4444 --MultipleServerPorts=1 --CGIPort=4500 --CGICallbackPort=4600 --MinServerProcs=2 --MaxServerProcs=2 > c:\\xxxx\\tmp\\WebDaemonTrace.log 2>&1";
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = workingDirectory;
startInfo.FileName = fileName;
startInfo.Arguments = arguments;
Process process = new Process();
process.StartInfo = startInfo;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
Gives an error. The process created and shows up in taskmanager, but after 5 seconds it disappears. Furthermore i can read in a debug message that:
"commandline argument '>' is unknown"
I cannot seem to find the problem. Open to any suggestions :-)
in command prompt we can get list of ACTIVE user's IP [on LAN] using command like
arp - g
How can I get similar list using C#
You can use Process to execute commands from c# program
Try This:
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "arp";
startInfo.Arguments = "-g";
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
String strData = process.StandardOutput.ReadToEnd();
I am trying to execute commands on Mingw from other process with this code:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"PATH-TO-MINGW\mingwenv.cmd";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
using (Process exeProcess = Process.Start(startInfo))
{
StreamWriter str = exeProcess.StandardInput;
str.WriteLine("ls");
exeProcess.WaitForExit();
}
but this code just lunches Mingw and does not input command.
Do I miss something or it is not possible to do?
Thanks
Update
Based on Jason Huntleys answer, solution for me looks like this (I am using OMNeT++ simulator so directories are based on it)
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"PATH_TO_SIMULATOR\omnetpp-4.3\msys\bin\sh.exe";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
using (Process exeProcess = Process.Start(startInfo))
{
using (StreamWriter str = exeProcess.StandardInput)
{
str.WriteLine("cd PATH_TO_SIMULATOR/omnetpp-4.3");
str.Flush();
str.WriteLine("ls");
str.Flush();
}
exeProcess.WaitForExit();
}
I suspect c# is launching your mingw command in a CMD prompt. You need to spawn your process within a bash shell. Try wrapping your command with "bash -l -c 'ls'" or "bash -c 'ls'". Make sure bash is in your PATH, and be sure you quote command arguments, if any. I've had to use this method when I spawn bash commands from popen in python. I know diff language, but could be related.
I imagine the code will look similar to this. I haven't tested in C#:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "bash.exe";
startInfo.Arguments = "-l -c 'ls -l /your/msys/path'";
# Or other examples with windows path:
# startInfo.Arguments = "-l -c 'ls -l /c/your/path'";
# startInfo.Arguments = "-l -c 'ls -l C:/your/path'";
# startInfo.Arguments = "-l -c 'ls -l C:\\your\\path'";
process.StartInfo = startInfo;
process.Start();
you should do
str.Flush();
so the command you've writen is passed to the process.
also you should use using statement when dealing with streams
using (Process exeProcess = Process.Start(startInfo))
{
using(StreamWriter str = exeProcess.StandardInput)
{
str.WriteLine("ls");
str.Flush();
exeProcess.WaitForExit();
}
}