Execute Unix commands using putty in C# [duplicate] - c#

This question already has answers here:
Run Unix commands using PuTTY in C# [duplicate]
(2 answers)
Closed 3 years ago.
Hi I have the below code,
I am able to open putty session but i was not able to give the inputs using C# , i have tried using process.StandardInput.WriteLine but it is not working . Please help me.
class Program
{
static void Main(string[] args)
{
Process process = new Process();
process.StartInfo.FileName = #"C:\Users\win7\Desktop\putty.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.Arguments = "-ssh mahi#192.168.37.129 22 -pw mahi";
process.Start();
process.StandardInput.WriteLine("ls");
}
}
Hi All , I Have used Plink instead of putty by the suggestion given by Onots.
I have done the following
1.Edited my path in environment variable to my plink location i.e., D:\Plink\
2.Manually Opened Command Prompt and Logged into my host server using plink using the command
plink-0.57.exe -ssh mahi#192.168.37.129 -pw mahi and i am able to execute commands manually.
3.Now i have modified the code as below
class Program
{
static void Main(string[] args)
{
Process process = new Process();
process.StartInfo.FileName = #"D:\Plink0.57\plink-057.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.Arguments = " -ssh mahi#192.168.37.129 -pw mahi";
process.Start();
process.StandardInput.WriteLine("ls");
}
}
But i was not able to open plink and the command is not executing using C#. But what happens is , a command prompt just appears and closes immediately , i have figured the error message as
"Unable to write to standard input"
Please help me ,i am not able to proceed any further. Thanks In Advance.

Wouldn't it be easier to use the command line Plink (PuTTY Link) instead of the GUI? I believe that it is more suitable for automated tasks.
See http://the.earth.li/~sgtatham/putty/0.63/htmldoc/Chapter7.html#plink for example usage.
I will quote the relevant part here, just in case the link goes bad:
7.2.2 Using Plink for automated connections
More typically Plink is used with the SSH protocol, to enable you to
talk directly to a program running on the server. To do this you have
to ensure Plink is using the SSH protocol. You can do this in several
ways:
Use the -ssh option as described in section 7.2.1. Set up a PuTTY
saved session that describes the server you are connecting to, and
that also specifies the protocol as SSH. Set the Windows environment
variable PLINK_PROTOCOL to the word ssh. Usually Plink is not invoked
directly by a user, but run automatically by another process.
Therefore you typically do not want Plink to prompt you for a user
name or a password.
Next, you are likely to need to avoid the various interactive prompts
Plink can produce. You might be prompted to verify the host key of the
server you're connecting to, to enter a user name, or to enter a
password.
To avoid being prompted for the server host key when using Plink for
an automated connection, you should first make a manual connection
(using either of PuTTY or Plink) to the same server, verify the host
key (see section 2.2 for more information), and select Yes to add the
host key to the Registry. After that, Plink commands connecting to
that server should not give a host key prompt unless the host key
changes.
To avoid being prompted for a user name, you can:
Use the -l option to specify a user name on the command line. For
example, plink login.example.com -l fred. Set up a PuTTY saved session
that describes the server you are connecting to, and that also
specifies the username to log in as (see section 4.14.1). To avoid
being prompted for a password, you should almost certainly set up
public-key authentication. (See chapter 8 for a general introduction
to public-key authentication.) Again, you can do this in two ways:
Set up a PuTTY saved session that describes the server you are
connecting to, and that also specifies a private key file (see section
4.20.8). For this to work without prompting, your private key will need to have no passphrase. Store the private key in Pageant. See
chapter 9 for further information. Once you have done all this, you
should be able to run a remote command on the SSH server machine and
have it execute automatically with no prompting:
Z:\sysosd>plink login.example.com -l fred echo hello, world hello,
world
Z:\sysosd> Or, if you have set up a saved session with all the
connection details:
Z:\sysosd>plink mysession echo hello, world hello, world
Z:\sysosd> Then you can set up other programs to run this Plink
command and talk to it as if it were a process on the server machine.

The following code gives the solution
class Program
{
static void Main(string[] args)
{
ProcessStartInfo startinfo = new ProcessStartInfo();
startinfo.FileName = #"D:\Plink0.57\plink-057.exe";
startinfo.Arguments = "-ssh mahi#192.168.37.129 -pw mahi";
Process process = new Process();
process.StartInfo = startinfo;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.Start();
process.StandardInput.WriteLine("ls");
process.WaitForExit();
Console.ReadKey();
}
}

Related

c# ssh conneciton and command problems

I would like to connect use ssh to connect to an other computer. Following you can see my code.
ProcessStartInfo startinfo = new ProcessStartInfo();
startinfo.FileName = #"C:\Program Files (x86)\PuTTY\putty.exe";
startinfo.Arguments = "-ssh <user>#<domain> -pw <password>";
Process process = new Process();
process.StartInfo = startinfo;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.Start();
process.StandardInput.WriteLine("<command>");
process.WaitForExit();
Console.ReadKey();
With that I have two problems. Firstly, the command should wait until the connection is successful established. Secondly, the command is not shown in the cmd. I don't know if don't see the commands because it's not waiting until the connection is successful or it is just not working.
I really appreciate any help.
Using the GUI application "Putty" to initiate a ssh connection is not optimal. First of all, Putty just gives you a messagebox with an error in it on an unsuccesfull connection attempt, e.g.
In your program-logic, you have no way of reacting to this event, since everything is handled by Putty and nothing is written to stdout or stderr. Also, the program hangs until the user clicks a button when such an error occures, thus requiring user interaction to even get the program to exit. I'm not sure wether Putty even gives you a meaningfull exitcode after the user closes the window, which you can use after the execution of the program.
So, all you could do is hope for the connection to be successfull. But you get no reaction on when the connection has been established. The best shot you have is doing a Thread.Sleep() for a while, then writing into stdin. I'm not sure wether you can control what Putty shows in the GUI through stdin (it doesn't seem to show up according to your information) or stdout.
Overall, starting a Putty process to establish an ssh connection is the wrong approach. You should look at external libraries such as https://sshnet.codeplex.com/ or the C# WinSCP library and the Session.ExecuteCommand() method. It should be as easy as shown in the code here. Using C# libraries, you also have a much, much better control over handling connection errors, timeout errors, command execution errors and reacting on command outputs.

Starting a process

As part of SharePoint automation testing, I am trying to open Internet Explorer as another user by using the System.Diagnostics.Process . Here is the following C# code
System.Diagnostics.Process p = new System.Diagnostics.Process();
// Domain and User Name:
p.StartInfo.Domain = "MYDOMAIN";
p.StartInfo.UserName = "myusername";
// Command to execute and arguments:
p.StartInfo.FileName = "C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe";
p.StartInfo.Arguments = "http://url/AllItems.aspx";
// Build the SecureString password...
System.String rawPassword = "thepassword";
System.Security.SecureString encPassword = new System.Security.SecureString();
foreach (System.Char c in rawPassword)
{
encPassword.AppendChar(c);
}
p.StartInfo.Password = encPassword;
// The UseShellExecute flag must be turned off in order to supply a password:
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = false;
p.Start();
When I run this automated test Visual Studio returns informing me that the test was successful, however Internet Explorer does not open.
Is there something in my code I am missing in order for a window to appear? There is no iexplore process running prior to the test being run.
putting double quotes around the file path (since it contains spaces) may help:
p.StartInfo.FileName = "\"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe\""
^^ ^^
In addition, if your intention is to start this from a service process or dll running in a service such as "SharePoint", then this code will probably not launch the process in the desktop desired. You'll need to set the desktop to "winsta0\\default" in the startup info.
To run a process the worker process should have high privileges and this is not an ideal case in any web application. If your purpose is to use IE for unit testing then I would consider using something like WaitIN. If your purpose is for application logic to access a URL and do something then consider using HttpWebRequest. If you still need a process to be started then create a Windows Service and then expose a web call so in Share Point you can just make a call and your Windows Service can run on local account or some other high privilege account.
Hope this helps and please provide the scenario why you want to start the IE and that can give you a better answer in the forum.

Why is my application failing when launched remotely?

I have a Windows application that sits on four different servers, its purpose is to look through a directory, find .wav files and copy them to a remote location. It works perfectly when ran from directory it's in on the server, but I don't like going to four different servers to execute the application. So below, I have a console app that is really just telling the user to store the IDs for the wav files in the right location so the four applications can see them, then executes the various programs. The problem is all four apps crash immediately after launch, I think it has something to do with how I'm executing the command, but I can't figure it out. Any ideas?
class Program
{
static void Main()
{
Console.SetWindowSize(90, 35);
Console.WriteLine(#"Place the ID of the interaction(s) you wish to recover in \\SERVER\c$\IDKeys.txt." + Environment.NewLine);
Console.WriteLine("Press Enter to find interactions.");
Console.ReadLine();
exeCmd();
}
static void exeCmd()
{
string[] executable =
{
#"\\Server1\C$\App\findwavs.exe",
#"\\Server2\C$\App\findwavs.exe",
#"\\Server3\C$\App\findwavs.exe",
#"\\Server4\C$\App\findwavs.exe"
};
foreach (string exe in executable)
{
Process proc = new Process();
proc.StartInfo.FileName = exe;
proc.Start();
}
}
}
The code you have executes the executable on the local machine.
Using #"\\Server1\C$\App\findwavs.exe does not mean that the executable will run on Server1, it just means that your local machine will look in this network path to obtain the executable file, but will run it locally.
You can use PsExec to execute an application on a remote machine.
Consider the following code that uses PsExec to run an executable on a remote machine:
string application = "c:\\app\\findwavs.exe";
string arguments = ""; //use this if you want to pass any command line arguments to the findwavs.exe executable
string location_of_psexec = "c:\\pstools\\psexec.exe"; //location of Psexec.exe on local machine
string remote_machine = "Server1"; //name of remote machine
Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = location_of_psexec;
process.StartInfo.Arguments = string.Format("\\\\{0} -c \"{1}\" \"{2}\"", remote_machine, application, arguments);
This code assumes that the application path (e.g. "c:\app\findwavs.exe") is relative to your local machine, not the remote machine.
If you want to use a path relative to the remote machine, simply remove the -c from the value of process.StartInfo.Arguments
UPDATE:
Quoting from the above reference:
If you omit a user name, the process will run in the context of your account on the remote system, but will not have access to network resources (because it is impersonating). Specify a valid user name in the Domain\User syntax if the remote process requires access to network resources or to run in a different account. Note that the password and command are encrypted in transit to the remote system.
To make you application able to access network resources, use the -u and -p switches to supply a username and a password.
Running your code would be equivalent to navigating to \\Server1\C$\App\findwavs.exe in Explorer and double clicking on the exe. What I mean by this is that it will run the program on the machine that told it to run, not where the exe is stored.
The easiest way I can see to accomplish the task you want to perform would be to use PsExec.

Change System Date in Windows 7+ via C# windows Service with Domain User [duplicate]

This question already has answers here:
Running CMD as administrator with an argument from C#
(5 answers)
Closed 8 years ago.
kindly help me to solve the following problem.
I am trying to change computer Date via C# Windows Service. The following command
this command is working in C# windows application if i run it as RUN AS Administrator. but the service is not changing system date by the following command. my pc is on domain and i run this service as domain service account. also i add service#domain account to system administrator group.
string strCmdText = "/c DATE ";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);
how could i run cmd as run As Administrator in C# Service which is already run as domain user.
i tried all the solutions which is provided here but still the problem is remain.
To run CMD in administrator privilage, you simply have to run an application in administrator privilage.
But better way to call an program from console will be using Process object (not static method), where you have more options, eg. can read output, etc.
Process p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "date";
p.StartInfo.Arguments = "";
p.Start();
Then to input data to the application you have to use StandardInput field of Process class
p.StandardInput.Write(string yourDate);
And at the end you can gently wait for application to finish it's job.
p.WaitForExit();
To read data from output you have to use this command:
string output = p.StandardOutput.ReadToEnd();
You can also read this line by line (if you have to):
string[] oLines = output.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);

how to publish website using cmd

is it possible to replicate this using cmd in c#
Yes, if you're just talking about pushing content up to a site, I'm working on such a beast now.
My proof-of-concept used a Process object to simply run a cmd.exe script that used FTP:
using System.Diagnostics;
:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "myUpload.cmd";
p.Start();
p.WaitForExit();
The program published the web site (it wasn't an actual web site but similar enough that the same method can be used) locally and used the browser to open the file (this was static content only so no need for a web server).
Then, once validated by the user, it simply created a script file temp.ftp containing all the relevant commands and used ftp -s:temp.ftp -n test.com within myUpload.cmd to do the file transfer. The -s specifies the script to run and the -n stops automatic login. That's so you can dynamically create a user command in your script to log in.
The final version will actually probably run Python code so I don't have to fight the brain-deadedness of cmd.exe but the theory is the same.

Categories