I am working on creating a GUI to interface with a Citrix XEN server. I dont know how to execute commands from my within my application on my widows system on the XEN Server.
I was thinking using SSH but again I dont know how. Does anyone have an example of how to do this? How to establish a SSH tunnel when the user pushes a button? I want to be able to run the command xe vm-list and then display the output in a label. Thats just to start my next one will be to create a VM and name is what the user wants, but for now I just need to figure out how to execute commands on the XEN Server.
I have used SharpSSH with great success.
This can be downloaded from http://www.tamirgal.com/blog/page/SharpSSH.aspx.
Finding yourself an ssh component will allow you to do more meaningful things, but at the base level, you can do something like this:
public void ExecuteExternalCommand(string command)
{
try
{
// process start info
System.Diagnostics.ProcessStartInfo processStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
processStartInfo.RedirectStandardOutput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.CreateNoWindow = true; // Don't show console
// create the process
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = processStartInfo;
process.Start();
string output = process.StandardOutput.ReadToEnd();
Console.WriteLine(output);
}
catch (Exception exception)
{
//TODO: something Meaninful
}
}
Which will let you run arbitrary external executables via the cmd.exe interface and then respond to it.
Here's some Links:
Example Code's SSH Component
[MSDN Process Class docs][2]
Related
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.
So i have WCF server running on remote machine.
This server received simple string as argument and i want this argument to execute via command line.
This is the function on the server side that need to execute the command:
public void ExecuteCmdCommand(string arguments)
{
log.Info(arguments);
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Maximized;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = arguments;
log.Debug(startInfo.Arguments);
process.StartInfo = startInfo;
process.OutputDataReceived += (sender, args) =>
{
log.Info(args.Data);
};
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
}
As you can see at the beginning of this function i am print to my console the command that received.
So i try to start notepad by pass the argument notepad, i can see via the console that the command is received on the server side so i am can be sure that the communication works but nothing happened.
What i am doing wrong ? same command on my local machine start notepad.
Update
OK notepad work fine (also without .exe at the end) but when i am send the command appium (i want to start my appium server) i got this error when send the command to the server (but the server received 'appium' command):
System.ServiceModel.FaultException: 'The server was unable to process
the request due to an internal error. For more information about the
error, either turn on IncludeExceptionDetailInFaults (either from
ServiceBehaviorAttribute or from the configuration
behavior) on the server in order to send the exception information
back to the client, or turn on tracing as per the Microsoft .NET
Framework SDK documentation and inspect the server trace logs.'
The FileName of the process is not correct, "cmd.exe". You could try this:
ProcessStartInfo startInfo = new ProcessStartInfo(arguments);
startInfo.WindowStyle = ProcessWindowStyle.Maximized;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
and in the arguments pass the following:
notepad.exe
For a detailed overview of ProcessStartInfo class please have look here.
I suggest you think about the case in which you want to pass in arguments also some arguments related with the process you want to start. For instance, you may want to start notepad and open a file. The file should be passed also as an argument. So I think that a rather better approach it would be to make arguments an array of strings and follow the convention that the first element of the array is the program you want to start and the rest elements of the array are program's arguments.
I have two applications First one detects the USB/Portable HDD plugging in to the system, and this application then passes the detected Drive letter to another External application and External application ejects it.
The external application is always run as an administrator. It is working properly.
But there is an issue when "Do you want to run this application as admin YES/NO" popup appears, If I select Yes it works properly. Now If I select No even then the USB drive appears to be in use by First application and cannot be ejected manually.
My Code is given below
ProcessStartInfo start;
Process exeProcess = null;
try
{
start = new ProcessStartInfo();
start.Arguments = #"H:\";
start.Verb = "runas";
start.FileName = "Eject.exe";
start.WindowStyle = ProcessWindowStyle.Normal;
start.CreateNoWindow = false;
using (exeProcess = Process.Start(start))
{
exeProcess.WaitForExit();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
The Console output in the catch block shows the message "The operation has been canceled by user" but still the resource is in use.
Kindly guide me how to tackle this issue.
I have a Java .jar application that is ran from a .bat file to have arguments passed to the Java application. The application opens a console (cmd.exe to be exact), writes things to it regularly and accepts some commands. I'm trying to create a kind-of wrapper around it in C# Winforms to ease it's use. How can I run the .jar with the same arguments as are in the .bat file, capture realtime output and write execute commands?
Yes, it is possible to do this using the System.Diagnostics.Process class and the ProcessStartInfo class from the .NET Framework. The Process class is used to control (start / stop) the desired process (application) and the ProcessStartInfo class is used to configure the process instance that will be started (arguments, redirect input and output, show / hide process window, and so on).
The code for starting a jar file looks like this:
var jarFile = "D:\\software\\java2html\\java2html.jar");
// location of the java.exe binary used to start the jar file
var javaExecutable = "c:\\Program Files (x86)\\Java\\jre7\\bin\\java.exe";
try
{
// command line for java.exe in order to start a jar file: java -jar jar_file
var arguments = String.Format(" -jar {0}", jarFile);
// create a process instance
var process = new Process();
// and instruct it to start java with the given parameters
var processStartInfo = new ProcessStartInfo(javaExecutable, arguments);
process.StartInfo = processStartInfo;
// start the process
process.Start();
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
The usual way to start a jar file is:
java -jar file.jar
To be sure, that the process will find the (in this case java) executable, it is a good practice to specify the fully qualified path to the process you want to start.
In order to redirect the standard output of the application you are starting, you need to set the ProcessStartInfo.RedirectStandardOutput property to true and then use the Process.StandardOutput property stream to fetch the output of the started application. The modified code for the application from the example above looks like this:
// command line for java.exe in order to start a jar file: java -jar jar_file
var arguments = String.Format(" -jar {0}", jarFile);
// indicate, that you want to capture the application output
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
// create a process instance
var process = new Process();
// and instruct it to start java with the given parameters
var processStartInfo = new ProcessStartInfo(javaExecutable, arguments);
process.StartInfo = processStartInfo;
// start the process
process.Start();
// read the output from the started appplication
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
If you want to control the input too, set the ProcessStartInfo.RedirectStandarInput property to true and then use the Process.StandardInput property stream to send input data to the started application.
I found how to open cmd in C#.
But I can use Inputstream only once.
Create Cmd Process
ProcessStartInfo CmdInfo = new ProcessStartInfo();
Process cmd = new Process();
CmdInfo.FileName = #"cmd";
CmdInfo.WindowStyle = ProcessWindowStyle.Hidden;
CmdInfo.CreateNoWindow = true;
CmdInfo.UseShellExecute = false;
CmdInfo.RedirectStandardInput = true;
CmdInfo.RedirectStandardOutput = true;
CmdInfo.RedirectStandardError = true;
cmd.EnableRaisingEvents = false;
cmd.StartInfo = CmdInfo;
cmd.Start();
Now we can use cmd.StandardInput and cmd.StandardOutput.
Use Cmd
// Use cmd 1
cmd.StandardInput.WriteLine("cd");
cmd.StandardInput.Close(); // if don't close, I can't get output
Console.WriteLine( cmd.StandardOutput.ReadToEnd() ); // Done!
// Use cmd 2
cmd.StandardInput.WriteLine("cd C:\"); // It will occure ObjectDisposedException
I want solve this problem.
I don't think you're going to get far with that approach. The code is a hint ProcessStart ! It's a new process! After you've started the process it's completely seperate to the one in which your code resides, the only way you would be able to communicate with this new process is via COM or remoting or some other inter application communication channel... MSMQ etc.
As far as I know the cmd (command prompt) offers none of these.
I think you'll want to study up on powershell...
Calling PowerShell From C#
http://www.codeproject.com/Articles/18229/How-to-run-PowerShell-scripts-from-C
etc etc
The command shell executable will not process commands from a redirected standard input until the input is closed.
You have three choices:
Create a new process for each command.
Pipeline all of the commands that you want to execute, then close the standard input handle.
Create a batch file containing all of the commands and then execute that.
If you choose to create a new process for each command, use cmd.exe's "/C" command line switch to execute the command rather than passing it through standard input.