Execute cmd command on windows server with web app [duplicate] - c#

This question already has answers here:
Restart Server from ASP.NET application when AppPool is ran under LocalSystem or LocalService account
(2 answers)
Shutdown or Restart Machine In C# and ASP.NET
(1 answer)
Closed 3 years ago.
I have a web app c # hosted on IIS on a computer with windows server 2008, I ran a command on a windows server cmd through C#, but it doesn't work, I tried it locally on my computer and the command works, I don't know why it doesn't work on the computer with windows server, I use this source code,I put a log but doesn't throw any error.
protected void btnReboot_Click(object sender, EventArgs e)
{
try
{
//StartShutDown("-l");
StartShutDown("-f -r -t 5");
Log2("MNS OK");
}
catch (Exception ex)
{
Log2("MNS ERROR " + ex.ToString());
}
}
private static void StartShutDown(string param)
{
ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = "cmd";
proc.WindowStyle = ProcessWindowStyle.Hidden;
proc.Arguments = "/C shutdown " + param;
Process.Start(proc);
}

You can actually capture the error output from the process that was launched by redirecting the standard error. An example would be like this:
private static void StartShutDown(string param)
{
Process p = new Process();
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true; // You need to set this
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C shutdown " + param;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.Start();
string stdoutx = p.StandardOutput.ReadToEnd();
string stderrx = p.StandardError.ReadToEnd(); // here is where you get the error output string
p.WaitForExit();
Console.WriteLine("Exit code : {0}", p.ExitCode);
Console.WriteLine("Stdout : {0}", stdoutx);
Console.WriteLine("Stderr : {0}", stderrx);
}
Once you have the Stderr you can check its contents and, if it's not empty then you know an error occurred.

Related

How to run .Net Core process as a specific user?

So I'm trying to run an .exe on my windows server that requires a user with specific access rights to run it. Luckily I have those rights on the server and can run the executable just fine manually.
However when I want to run it from my code, which is a .net core console API application I encounter a problem saying: 'The handle is invalid'.
Here is the method where Im trying to achieve this:
public void UpdateDataSets()
{
try
{
Process processStart = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo(#"PathToExecutable.exe");
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.Arguments = $#"MyArguments";
startInfo.RedirectStandardOutput = true;
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.UserName = "MyUserName";
startInfo.Domain = "MyDomain";
startInfo.Password = new NetworkCredential("", "MyUserPassword").SecurePassword;
processStart.StartInfo = startInfo;
string textToRead;
using(Process process = Process.Start(startInfo))
{
textToRead = process.StandardOutput.ReadToEnd();
process.WaitForExit(20000); //time limit because maybe infinite, I dont know?
}
File.WriteAllText(#"StandardOutput.txt", textToRead);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace.ToString());
}
}
I first tried with startInfo.Verb = "runas" and with startInfo.LoadUserProfile = true before hard-coding my active directory credentials, but I just got different errors there.
What am I doing wrong here?

Command won't run in Command Prompt

When users click on a button, I want it to run the logon script(launching from server), but each computer in different servers, so I get the server name. But the netlogon.StartInfo.Arguments = slnres + #"/c \netlogon\logon.cmd"; line is not working as it should be. It should run the logon.cmd on the PC(mapping network drivers, printers, etc), and then the CMD should close.
private void MapNetwork_Click(object sender, EventArgs e)
{
Process sln = new Process();
sln.StartInfo.UseShellExecute = false;
sln.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
sln.StartInfo.FileName = "cmd.exe";
sln.StartInfo.Arguments = "/c echo %logonserver%";
sln.StartInfo.RedirectStandardOutput = true;
sln.Start();
string slnres = sln.StandardOutput.ReadToEnd();
label1.Text = slnres;
Process netlogon = new Process();
netlogon.StartInfo.UseShellExecute = false;
netlogon.StartInfo.FileName = "cmd.exe";
netlogon.StartInfo.Arguments = slnres + #"/c \netlogon\logon.cmd";
netlogon.Start();
}
A couple things:
You don't need to run a command prompt to get an environment variable. You can use Environment.GetEnvironmentVariable.
Your Arguments property for your call to logon.cmd is being constructed into this:
\\myserver/c \netlogon\logon.cmd
When I think you want this:
/c \\myserver\netlogon\logon.cmd
So make sure you put slnres at the right place in your string. Your code should look like this:
private void MapNetwork_Click(object sender, EventArgs e)
{
string slnres = Environment.GetEnvironmentVariable("logonserver");
label1.Text = slnres;
Process netlogon = new Process();
netlogon.StartInfo.UseShellExecute = false;
netlogon.StartInfo.FileName = "cmd.exe";
netlogon.StartInfo.Arguments = "/c " + slnres + #"\netlogon\logon.cmd";
netlogon.Start();
}
i am a little confused about your question and i am not rly sure if i understand you correctly. some time ago i made a program where i had to run few powershell commands, so i made a class for it. redirected to your button it would look like that:
(and remember you need the fqdn to your file location => Reading File From Network Location)
using System.Diagnostics;
//class lvl scope vars
string output;
string ErrorOutput;
private void MapNetwork_Click(object sender, EventArgs e)
{
//define process arguments
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"cmd.exe";
startInfo.Arguments = #"FQDN path to your file on the server; exit";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
//start process
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
//outpunt handling
if (string.IsNullOrEmpty(ErrorOutput))
{
return output;
}
else
{
return ErrorOutput;
}
}
first of all i would check if your application is able to open the file one the shared network location. (server available? access rights to server? serer mapped?)
after that you can check if he is able to start the file locally. (does it need admin rights to run the *.cmd, *.bat file)
now you can check if your application runs it correctly.

C# Process Start Stuck

I wrote a simple TCP Server application,
when the program gets the request it will call an exe file to do something.
The application works fine on my PC.
But when I run on another PC the thread will stuck because it stuck in process start, so I checked the task manager whether the exe file did run. and it really work.
I have no idea how to solve it.
Here is my code:
System.Diagnostics.Process process = new System.Diagnostics.Process();
string path = System.Environment.CurrentDirectory;
process.StartInfo.WorkingDirectory = path;
process.StartInfo.FileName = "FileTransferTool\\FileTransfer.exe";
process.StartInfo.Arguments = argument;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.CreateNoWindow = false;
process.Start(); // the thread stuck here
I print out the message, it shows
System.ComponentModel.Win32Exception (0x80004005):
The system cannot find the file specified at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startIn
fo)
at System.Diagnostics.Process.Start() at ClassPackage.DsUploadFiletoNC.Start(Object[] param)
I have solved this problem by adding another process to call cmd.exe on the top of the main program, the code shown as below :
And the program will run as Administrator, but I don't know why
static void Main(string[] args)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
string path = System.Environment.CurrentDirectory;
process.StartInfo.WorkingDirectory = #"C:\Windows\System32";
process.StartInfo.FileName = "cmd.exe";
//process.StartInfo.FileName = "FileTransferTool\\circle.txt";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardInput = true;
//process.StartInfo.CreateNoWindow = false;
process.Start();
using (TCPServer server = new TCPServer())
{
server.Start();
Console.WriteLine("Socket Server Start...");
Console.ReadKey(true);
}
}

Windows Service fails to execute mshtml.dll

I have a Windows Application which uses mshtml.dll. It works fine within my Windows Form application.
When I use the same code within my Windows Service app then it fails. My Service runs as an Administrator.
below is the code I use:
private string PrintUsingPrinterExe(string Command)
{
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + Command);
// 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();
proc.StartInfo = procStartInfo;
proc.Start();
//StreamWriter streamWriter = proc.StandardInput;
//StreamReader outputReader = proc.StandardOutput;
//StreamReader errorReader = proc.StandardError;
//while (!outputReader.EndOfStream)
//{
// string text = outputReader.ReadLine();
// streamWriter.WriteLine(text);
//}
//while (!errorReader.EndOfStream)
//{
// string text = errorReader.ReadLine();
// streamWriter.WriteLine(text);
//}
//streamWriter.Close();
proc.WaitForExit(12000);
// Get the output into a string
string result = proc.StandardOutput.ReadToEnd();
if (!proc.HasExited)
{
proc.Kill();
}
// Display the command output.
return result;
}
command is : PRINTHTML.EXE url="http://www.google.com" printername="Brother HL-2270DW series" title="" header="" footer=""
Under event Log I find this:
Faulting module path: C:\Windows\SYSTEM32\mshtml.dll
So, how could it be possible that same DLL works just fine under winForm app and does not work under Windows Service.
BTW, same service runs fine on Windows 7.
so issue is Windows 10 + mshtml.dll + Windows Service

transfer files from windows to linux?

I'm trying to connect to a linux machine via pLink and PuTTY to transfer some .txt file. Right now I'm just trying to make the connection work. I have a small window with 2 textboxes (username,linux1) and a password box (pwbox1), and a button that when you click, it should connect you to the linux machine!
Here's my code:
private void button1_Click(object sender, RoutedEventArgs e)
{
string user = username.Text;
string passw = pwbox1.Password;
string linuxHst = linux1.Text;
ProcessStartInfo psi = new ProcessStartInfo(#"C:\Program Files (x86)\PuTTY\plink.exe", user + "#" + linuxHst + " -pw " + passw);
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.WindowStyle = ProcessWindowStyle.Normal;
psi.UseShellExecute = false;
psi.CreateNoWindow = false;
Process process = Process.Start(psi);
process.WaitForExit(5000);
}
The problem is that when I try this with the console application it works, without the textboxes! but I need it to work with WPF.
Can anyone please tell me what I'm doing wrong? am I missing something?

Categories