How to display Command window when executed from ASP.net web application - c#

My application was built on .NET Windows Forms
I have to convert the application to work as web application now.
Many fuctions have worked with no change what so ever
I used to have a function that executes command and opens command prompt window.
I put the code in ASP.net web application, the code is fine and commands get executed but the problem is that command prompt window does not show any more.
The code has not changed.
I wonder how can I get command prompt window appear in the server-side so admin can know if there is command error or any other issues?
This is the function that I use to execute a command
static void ExecuteCommand(string command, string workingFolder)
{
var processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
processInfo.UseShellExecute = false;
processInfo.WorkingDirectory = workingFolder;
var process = Process.Start(processInfo);
process.WaitForExit();
}

From the documentation you can keep open the command window with "/K" flag
If the fileName parameter represents a command (.cmd) file, the
arguments parameter must include either a "/c" or "/k" argument to
specify whether the command window exits or remains after completion.
var processInfo = new ProcessStartInfo("cmd.exe", "/k " + command);
processInfo.WorkingDirectory = workingFolder;
var process = Process.Start(processInfo);
process.WaitForExit();
But in order to get the error and show it to your admin you have to use StandardError and you can see the examples in the documentation.

Related

How to execute 2 different commands cmd on C#

I was working on a project which needs to run two cmd commands on C#, I looked up on how to do it but nothing worked for me, and everyone was giving the solution to execute only one cmd command.
I would like to execute one command when the user clicks a button, then another one right after, without quitting the cmd, and if possible to hide the cmd window.
My goal would be to execute the 2 following commands in the cmd, to run a Run.bat file:
cd C:\users\user\documents\file
Run.bat
Thanks.
You can directly call "C:\users\user\documents\file\Run.bat" and set the working directory as well as the shell execute flag :
string path = #"C:\users\user\documents\file\";
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = path + "Run.bat";
process.StartInfo.WorkingDirectory = path;
process.StartInfo.UseShellExecute = true;
process.Start();
//process.WaitForExit();

c# open cmd.exe process and Execute multiple commands

I would like to be able to open cmd and execute two commands from the window. First I would like to navigate to a particular directory where I can then run the second command from. Running a single command is pretty easy as this is all I have to do:
string path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + #"\Cisco Systems\VPN Client\";
Process process = new Process();
ProcessStartInfo processInfo = new ProcessStartInfo("cmd.exe", #"/c cd " + path );
process.StartInfo = processInfo;
process.Start();
However am not sure of the way to add the second argument so it runs after cmd runs the first command. Some research led me to this code snippet. Am unsure if this works since my aim is to start cisco vpn client from cmd and this seems not to start it. Here is the code:
string path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + #"\Cisco Systems\VPN Client\";
Process process = new Process();
ProcessStartInfo processInfo = new ProcessStartInfo("cmd.exe", #"/c cd " + path + "-t vpnclient connect user validuser pwd validpassword nocertpwd validconnectionentry ");
process.StartInfo = processInfo;
process.Start();
I once started the vpn client from cmd with the credentials just to make sure they were valid and it worked but I cant pull it off via C# programmatically.
Regards.
There three things you can do to achieve what you want. The easiest is to set the working directory of the process through ProcessStartInfo. This way you will only have to execute the command to start the VPN client.
The second option is redirecting the input and output of the process. (Also done through the ProcessStartInfo) This is something you want to do if you need to send more input to the process, or when you want to retrieve the output of the process you just started.
The third option is to combine the two commands with the & symbol. Using the & symbol makes cmd.exe execute the two commands sequentially (See here for an overview of the available symbols). Using this option will result in a command like this: /c cd path & vpnclient.
However because you just want to change the working directory of the process using the first option makes your code more readable. Because people reading your code do not need to know the & symbol in bash to understand what your code does. Changing the working directoy is done with the WorkingDirectory (MSDN) property of ProcessStartInfo (MSDN). See the following code:
var processInfo = new ProcessStartInfo("cmd.exe", #"/c vpnclient connect user validuser pwd validpassword nocertpwd validconnectionentry ");
processInfo.UseShellExecute = false;
processInfo.WorkingDirectory = path;
You can use & to execute next command or && to execute following command only if the previous one succeeded.
Examples:
dir /b & cls
and
taskkill /f /im explorer.exe && start explorer

Writing and executing multiple lines sequentially in an elevated command prompt using c#

Am a Newbie in C# and I have 3 commands(command2, command3 and command4) I need to execute in the elevated command prompt and I will also like to view the execution process as it happens. Currently, the problem is that the code below just opens the elevated command prompt and without executing the commands. I also seek better interpretations of the lines if wrong.
My code and Interpretation/Understanding of each line based on reviews of similar cases: ConsoleApp1
class Program
{
static void Main(string[] args)
{
string command2 = #"netsh wlan";
string command3 = #" set hostednetwork mode=true ssid=egghead key=beanhead keyusage=persistent";
string command4 = #" start hostednetwork";
string maincomm = command2.Replace(#"\", #"\\") + " " + command3.Replace(#"\", #"\\") ; //I merged commands 2 and 3
ProcessStartInfo newstartInfo = new ProcessStartInfo();
newstartInfo.FileName = "cmd"; //Intend to open cmd. without this the newProcess hits an error saying - Cannot run process without a filename.
newstartInfo.Verb = "runas"; //Opens cmd in elevated mode
newstartInfo.Arguments = maincomm; //I intend to pass in the merged commands.
newstartInfo.UseShellExecute = true; //
newstartInfo.CreateNoWindow = true; // I intend to see the cmd window
Process newProcess = new Process(); //
newProcess.StartInfo = newstartInfo; //Assigns my newstartInfo to the process object that will execute
newProcess.Start(); // Begin process and Execute newstartInfo
newProcess.StartInfo.Arguments = command4; //I intend to overwrite the initial command argument hereby passing the another command to execute.
newProcess.WaitForExit(); //
}
}
This is what I did to overcome the challenge and It gave me exactly what I wanted. I modified my code to use the System.IO to write directly to the elevated command prompt.
ProcessStartInfo newstartInfo = new ProcessStartInfo();
newstartInfo.FileName = "cmd";
newstartInfo.Verb = "runas";
newstartInfo.RedirectStandardInput = true;
newstartInfo.UseShellExecute = false; //The Process object must have the UseShellExecute property set to false in order to redirect IO streams.
Process newProcess = new Process();
newProcess.StartInfo = newstartInfo;
newProcess.Start();
StreamWriter write = newProcess.StandardInput ; //Using the Streamwriter to write to the elevated command prompt.
write.WriteLine(maincomm); //First command executes in elevated command prompt
write.WriteLine(command4); //Second command executes and Everything works fine
newProcess.WaitForExit();
Referrence: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardinput(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx
I think an understanding of some properties of the ProcessStartInfo might clear things.
The verb - Gets or sets the verb to use when opening the application or document specified by the FileName property.,
+The UseShellExecute - Gets or sets a value indicating whether to use the operating system shell to start the process.
+The FileName - Gets or sets the application or document to start MSDN Docs
When you use the operating system shell to start processes, you can start any document (which is any registered file type associated with an executable that has a default open action) and perform operations on the file, such as printing, by using the Process object. When UseShellExecute is false, you can start only executables by using the Process object Documentation from MSDN.
In my case, cmd is an executable. the verb property is some thing that answers the question "How should my I run my FileName(for executables e.g cmd or any application)?" for which I answered - "runas" i.e run as administrator. When the FileName is a document (e.g `someFile.txt), the verb answers the question "What should I do with the file for which answer(verb) could be -"Edit","print" etc. also?"
use true if the shell should be used when starting the process; false if the process should be created directly from the executable file. The default is true MSDN Docs - UserShellInfo.
Another thing worth noting is knowing what you are trying to achieve. In my case, I want to be able to run commands via an executable(cmd prompt) with the same process - i.e starting the cmd as a process I can keep track of.

Hide Command Window in C# Application

Before you say its a duplicate question, please let me explain (as I've read all similar threads).
My application has both of these settings:
procStartInfo.CreateNoWindow = true;
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
and is also has WindowsApplication as the output type.
The black window STILL comes up when I call a command line command. Is there anything else I can do to hide the window? It doesn't happen for all commands, XCOPY is a situation where it the black window does flash up. This only happens though when the destination I'm XCOPYing too already contains the file and it's prompting me if I want to replace it. Even if I pass in /Y it will still flash briefly.
I'm open to using vbscript if that will help, but any other ideas?
The client will call my executable and then pass in a command line command ie:
C:\MyProgram.exe start XCOPY c:\Test.txt c:\ProgramFiles\
Here's the full code of the application:
class Program
{
static void Main(string[] args)
{
string command = GetCommandLineArugments(args);
// /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 " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = procStartInfo;
process.Start();
}
private static string GetCommandLineArugments(string[] args)
{
string retVal = string.Empty;
foreach (string arg in args)
retVal += " " + arg;
return retVal;
}
}
The problem is that you're using cmd.exe. Only its console window will be hidden, not the console window for the process you ask it to start. There's little point in using cmd.exe, unless you are trying to execute some of the commands it implements itself. Like COPY.
You can still suppress the window if you need cmd.exe, you'll have to use the /B option for Start. Type start /? at the command prompt to see options. Not that it helps, you can't use START COPY.
There's a specific quirk in xcopy.exe that might throw you off as well. It does not execute if you don't also redirect the input. It just fails to run without diagnostic.
i see that you are calling cmd and then passing the command as parameters. Instead call the command directly
e.g.
System.Diagnostics.ProcessStartInfo procStartInfo = new System.DiagnosticsProcessStartInfo("xcopy", "<sourcedir> <destdir> <other parameters>");
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
You can try adding
process.StartInfo.UseShellExecute = false;
to your process
If you are calling cmd.exe in your C# code and passing the commands to it via standard input.WriteLine and you don't want your CMD window to pop up every time you run your code, you can simply write this command:
test.StartInfo.FileName = "cmd.exe";
test.StartInfo.CreateNoWindow = true;
By setting create no window to false, we are running the command sent to the CMD in the background and the output is not being displayed to the user. By setting it to false, the CMD window pops up.
I had a similar task - It is possible to hide the window after creation via an API call.
(In your case you maybe need a helper thread.)
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
If you know the handle of the new Window you can call
ShowWindow(hWnd, 0);
0 hides the window, 1 shows the window
To get the handle of the Window take a look at:
pinvoke.net enumwindows(user32)

How can I pass more than one command line argument via c#

I need to pass more than one command line argument via c# for a process called handle.exe:
http://www.google.com.mt/search?sourceid=chrome&ie=UTF-8&q=handle.exe
First, I need to run the executable file via ADMINISTRATOR permissions. This post has helped me achieve just that:
programatically run cmd.exe as adminstrator in vista, c#
But then comes the next problem of calling the actual line arguments such as "-p explore"
How can I specify the command line arguments together, or maybe consecutively?
Current code is as follows:
Process p = new Process();
ProcessStartInfo processStartInfo = new ProcessStartInfo("filePath");
processStartInfo.CreateNoWindow = true;
processStartInfo.UseShellExecute = false;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.Verb = "runas";
processStartInfo.Arguments = "/env /user:" + "Administrator" + " cmd";
p.StartInfo = processStartInfo;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
Thanks
I believe the answer you are looking for is right out of the Runas command documentation.
runas /user:user#domain.microsoft.com "notepad my_file.txt"
It appears that the last argument to the runas command is the command that is being run along with any arguments. The key is to use quotes to group the actual command executable with it's arguments so that the values are not seen as separate arguments to the runas command but instead is issued as a single command on it's own.
So in your example you might want to do the following.
processStartInfo.Arguments = "/env /user:" + "Administrator" + " \"cmd -p explore\"";
You can run the process using the UseShellExecute command and pass in the username and password
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.useshellexecute%28v=VS.100%29.aspx
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.username%28v=VS.100%29.aspx
Although you will be storing the username and password somewhere.
If you are trying to run a process with elevated permissions, there may be a better way than calling runas.

Categories