Problem while trying to run .exe on remote with psexec (c#)? - c#

Hey all,
I'm trying to run an exe file ON A REMOTE MACHINE (not from, but ON).
I have very simple code as following:
ProcessStartInfo info = new ProcessStartInfo("C:\\PsTools");
info.FileName = "psexec \\\\" + machine.Name + "\\C\\Program Files\\test.exe";
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Process p = Process.Start(info);
When trying to run this code i get "The system cannot find the file specified" error.
There is a file named "test.bat" on the specified directory.
The remote machine is on the same domain and the C folder is shared (I'm the admin).
I have PsTools installed and configured as environment variables.
I have tried variety of codes (for example if i don't use "psexec" on the ProcessStartInfo constructor and on the FileName property, the bat file runs on the local machine instead of the remote one...) and nothing works!
any ideas?

My guess is that it's failing to find psexec, because you've set UseShellExecute to false. Try giving the full path to psexec.exe.
You should also set the FileName property to just the file you want to start, and the Arguments property to the command line arguments, like this:
ProcessStartInfo info = new ProcessStartInfo("C:\\PsTools");
info.FileName = #"c:\whatever\psexec.exe";
info.Arguments = #"""\\" + machine.Name + #"\C\Program Files\test.exe""";
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Process p = Process.Start(info);
Note that I've also added double quotes in the Arguments property so that it doesn't get split into two arguments due to "Program Files" having a space in it.

Related

how can I execute a shortcut(.lnk) using Process.Start()? [duplicate]

Is there a way to run an application via shortcut from a C# application?
I am attempting to run a .lnk from my C# application. The shortcut contains a significant number of arguments that I would prefer the application not have to remember.
Attempting to run a shortcut via Process.Start() causes an exception.
Win32Exception: The specified executable is not a valid Win32 application
This is the code I am using.
ProcessStartInfo info = new ProcessStartInfo ( "example.lnk" );
info.CreateNoWindow = true;
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
info.RedirectStandardInput = true;
Process whatever = Process.Start( info );
Could you post some code. Something like this should work:
Process proc = new Process();
proc.StartInfo.FileName = #"c:\myShortcut.lnk";
proc.Start();
Setting UseShellExecute = false was the problem. Once I removed that, it stopped crashing.
if your file is EXE or another file type like ".exe" or ".mkv" or ".pdf" and you want run that with shortcut link your code must like this.
i want run "Translator.exe" program.
Process.Start(#"C:\Users\alireza\Desktop\Translator.exe.lnk");
If you're using UseShellExecute = false and trying to launch a batch file make sure to add .bat to the end of the filename. You don't need .bat if UseShellExecute = true though. This made me just waste an hour of work... hoping to save someone else.

Run type as process in c#

I can join videos in windows at command line with
type vid1.avi vid2.avi > vidjoined.avi
I try to run this in c#:
ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
cmdStartInfo.FileName = "cmd.exe";
cmdStartInfo.Arguments = "type vid1.avi vid2.avi > vidjoined.avi";
Process cmdProcess = new Process();
cmdProcess.StartInfo = cmdStartInfo;
cmdProcess.Start();
cmdProcess.WaitForExit(120000);
What is wrong with my code?
It runs forever and I get no console output.
I'm not sure it's valid to concatenate two AVI files together, but that aside:
Try changing your arguments to:
cmdStartInfo.Arguments = "/c type vid1.avi vid2.avi > vidjoined.avi"
The "/c" will cause the command shell to execute and then exit.
Also, the working directory is going to be wherever cmd.exe is. Your relative paths to your files will likely not resolve properly. Either set cmdStartInfo.WorkingDirectory to the directory that your files are in, or use fully qualified paths in your arguments.

Deleting directory that contains items

I am trying to delete a directory using C#. The first method I tried was
Directory.Delete(#"C:\Program Files (x86)\Qmuzki32");
I get an exception stating that the directory is not empty. I then found a cmd command which I can use to delete the directory quietly regardless of the fact that the directory is empty or not. I ran the following command in cmd:
rmdir /s /q "C:/Program Files (x86)/Qmuzik32"
This worked and did exactly what I wanted it to do. With my first attempt I tried building this command into a C# process like so:
if (Directory.Exists(#"C:\Program Files (x86)\Qmuzik32"))
{
string sQM32Folder = #"C:\Program Files (x86)\Qmuzik32";
Process del = new Process();
del.StartInfo.FileName = "cmd.exe";
del.StartInfo.Arguments = string.Format("rmdir /s /q \"{0}\"", sQM32Folder);
del.WaitForExit();
}
This did not work and then I tried it like this:
if (Directory.Exists(#"C:\Program Files (x86)\Qmuzik32"))
{
string sQM32Folder = #"C:\Program Files (x86)\Qmuzik32";
Process del = new Process();
del.StartInfo.FileName = "rmdir.exe";
del.StartInfo.Arguments = string.Format("/s /q \"{0}\"", sQM32Folder);
del.WaitForExit();
}
Same problem. I get the exception:
No process is associated with this object.
I do think I am on the right track; maybe the code above just requires some tweaking.
Just use Directory.Delete(string, bool).
While the low-level filesystem APIs of course require you to make sure the directory is empty first, any half-decent framework abstracting them allows you do do a recursive delete. In fact, existence of such a method would be the first thing I'd check before even trying to resort to external programs.
If you want to use the cmd way you can use this:
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C rd /s /q \"C:\\Program Files (x86)\\Qmuzik32\"";
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
del.Start();
del.WaitForExit();
you didn't start the procces so it doesn't have a PID so it dies

problems with stdout and psexec.exe from sysinternals

i have searched and read about issues with psexec.exe from sysinternals not working properly with c# and stdout. i am now trying to figure out how to just call a batch file that has the following instead of using System.Diagnostics.Process to call psexec:
test.bat contains the following line:
psexec.exe \\hostname -u user -p password ipconfig /all >c:\test.txt
test.txt will be saved on the host where i am running my c sharp app and executing psexec.
when i execute the following:
System.Diagnostics.Process psexec_run = new System.Diagnostics.Process();
psexec_run.StartInfo.FileName = "cmd.exe";
psexec_run.StartInfo.Arguments = #"/c """ + cur_dir + #"\test\test.bat""";
psexec_run.StartInfo.UseShellExecute = false;
psexec_run.Start();
psexec_run.WaitForExit();
i see the cmd window pop up and it runs something but not sure what and goes away.
if i execute the following:
System.Diagnostics.Process psexec_run = new System.Diagnostics.Process();
psexec_run.StartInfo.FileName = cur_dir + "\\test\\psexec.exe";
psexec_run.StartInfo.Arguments = #"\\hostname -u user -p password ipconfig /all";
psexec_run.StartInfo.UseShellExecute = false;
psexec_run.Start();
psexec_run.WaitForExit();
then i see the command window open and it runs psexec which takes quite a few secs and i quickly see my output i need, but i have no way of capturing the output or writing it to a file.
i guess my issue now is since psexec will not work with stdout how can i capture the output from the psexec command to write it to a file???
see the following link for the issues with psexec, the last reply on this url mentioned a way to write the process output to a file without using stdout, i'm newbie to c# i can't figure out how to write process output without use stdout :(
http://forum.sysinternals.com/psexec-fails-to-capture-stdout-when-launched-in-c_topic19333.html
based on response below i tried the following:
ProcessStartInfo psi = new ProcessStartInfo(cur_dir + "\\test\\psexec.exe", #"\\hostname -u user -p password ipconfig /all");
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
StreamReader myStreamReader = p.StandardOutput;
// Read the standard output of the spawned process.
string sOutput = myStreamReader.ReadToEnd();
i did ReadToEnd so i would make sure it got all the output, it DID NOT!! for some reason it only go the first line of ipconfig output that was it. Also the cmd window it opened up never closed for some reason. even with CreateNoWindow=true the code just hangs. so again something is wrong with psexec and stdout i think?? as i can run this code just fine using ipconfig /all command on the local host and not use psexec...
again i am looking to avoid stdout and somehow find a way to get the output from this command or unless there is something else i'm over looking? also, not to make more work for anyone, but if you d/l psexec.exe from sysinternals and test it with a command on a remote host you will see. i have spent 2 days on this one :( trying to figure out how to use psexec or find some other quick method to execute remote command on a host and get ouptput.
UPDATE:
i gave up on psexec in c# code, i saw many posts about psexec eating the output, having a child window process ,etcc
until my head hurt :) so i am trying to run a batch file and output to a file and it's not making sense...
i have a batch file test.bat with the following
psexec.exe \\\hostname -u name -p password ipconfig /all >c:\test.txt
when i run the following code:
ProcessStartInfo psi = new ProcessStartInfo(cur_dir + #"\test\test.bat");
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
p.WaitForExit();
the cmd windows comes and goes really quickly and the test.txt file is created but is 0 bytes no info in it.
so if i run the batch file in a windows cmd line with the psexec command it works perfectly fine!!???
so then to verify psexec was the issue i changed the batch file to:
ipconfig /all >c:\test.txt
i execute my code above and it works fine creates the output in the test.txt file..???!!!!
why is not working with psexec am i missing something? if it's psexec, does anyone have
any recommendations for how i can execute a command on a remote windows host and get me the
output???
I have an answer to this problem that has worked for me.
Hopefully someone else will find it useful.
I have literally just spent the last two hours tearing my hair out with this. The psexec tool runs completely fine using a normal command prompt but when attempting to redirect the streams it truncates the output and you only get half output back.
In the end how I fixed my issue was a little bit of a hack. I piped the output of the command to a text file and read it back in to return it from the function.
I also has to set UseShellExecute to true. Without this it still wouldn't work. This had the unfortunate side effect of showing the console window. To get around that I set the window style to be hidden and hey presto it works!!!
Heres my code:
string ExecutePSExec(string command)
{
string result = "";
try
{
string location = AppDomain.CurrentDomain.BaseDirectory;
// append output to file at the end of this string:
string cmdWithFileOutput = string.Format("{0} >{1}temp.log 2>&1", command,location );
// The flag /c tells "cmd" to execute what follows and exit
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + cmdWithFileOutput);
procStartInfo.UseShellExecute = true; // have to set shell execute to true to
procStartInfo.CreateNoWindow = true;
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden; // as a window will be created set the window style to be hiddem
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
// now read file back.
string filePath = string.Format("{0}temp.log", location);
result = System.IO.File.ReadAllText(filePath);
}
catch (Exception objException)
{
// Log the exception
}
return result;
}
and its usage:
string command = #"psexec.exe -l -u domain\username -p password /accepteula \\192.168.1.3 netstat -a -n";
ExecutePSExec(command);
I had exactly same problem. i was getting "Windows ip config. " as first line when i run with psexec. i tried with paexec it worked well. I used Marius's code.
Note: if you dont use first cmd / c in arguments command runs only on local computer even if you define target as \\remoteserver
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe");
psi.Arguments = #"cmd/c C:\paexec.exe \\\192.168.2.5 -s -u test.local\administrator -p Password1 cmd /c ipconfig";
psi.CreateNoWindow = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
System.IO.StreamReader myStreamReader1 = p.StandardOutput;
p.WaitForExit();
string sOutput = myStreamReader1.ReadToEnd();
Are you sure your sourcecode is correct? that link is quite a bit old.. maybe its fixed!
Heres an example how to redirect the standard-output and put whole output in a string via streamreader:
ProcessStartInfo psi = new ProcessStartInfo("tftp.exe");
// preferences for tftp process
psi.CreateNoWindow = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
StreamReader myStreamReader = p.StandardOutput;
p.WaitForExit();
// Read the standard output of the spawned process.
string sOutput = myStreamReader.ReadToEnd();
i found a solution. apparently psexec is NOT going to work in c sharp. so i came up with some wmi code to connect to a remote host and it's working PERFECTLY!!! :)
i used microsoft's WMICodeCreator.exe to create wmi code for C# for the process method on a remote host, wow that tool is amazing because wmi code is little confusing to me.
psexec's output goes to StandardError and not StandardOutput. I don't know why it is that way. Following code snippet access it.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.RedirectStandardError = true;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
errors = process.StandardError.ReadToEnd();
process.Close();

Mimic Windows' 'Run' window in .NET

I would like to mimic the Run command in Windows in my program. In other words, I would like to give the user the ability to "run" an arbitrary piece of text exactly as would happen if they typed it into the run box.
While System.Diagnostics.Process.Start() gets me close, I can't seem to get certain things like environment variables such as %AppData% working. I just keep getting the message "Windows cannot find '%AppData%'..."
You can use the Environment.ExpandEnvironmentVariables method to turn %AppData% into whatever it actually corresponds to.
Depending on what you're trying to do, you could also call CMD.EXE, which will expand your environment variables automatically. The example below will do a DIR of your %appdata% folder, and redirect the stdOut to the debug:
StreamReader stdOut;
Process proc1 = new Process();
ProcessStartInfo psi = new ProcessStartInfo("CMD.EXE", "/C dir %appdata%");
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
proc1.StartInfo = psi;
proc1.Start();
stdOut = proc1.StandardOutput;
System.Diagnostics.Debug.Write(stdOut.ReadToEnd());

Categories