Launch an application on a remote PC using c# [duplicate] - c#

I'm trying to execute notepad.exe on a remote machine, but it's not working now. What am I missing?
var ui = new ImpersonateUser();
//the process to restart
const string processName = "notepad.exe";
var serverName = "serverName";
try
{
//Use adbadmin for access
ui.Impersonate(_domain, _userName, _pass);
//Start the process
ProcessStartInfo info = new ProcessStartInfo("C:\\PsTools");
info.FileName = #"C:\PsTools\psexec.exe";
info.Arguments = #"""\\" + serverName + #"C:\WINDOWS\notepad.exe""";
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Process p = Process.Start(info);
lblStatusResponse.Text = "Service " + processName + " was restarted correctly.";
}
catch (Exception ex)
{
lblStatusResponse.Text = ex.ToString();
}
finally
{
ui.Undo();
}
This gives me no exception, but I'm surely missing something...

The answer was a combination from your replies. But the whole correct solution was:
ProcessStartInfo info = new ProcessStartInfo("C:\\PsTools");
info.FileName = #"C:\PsTools\psexec.exe";
info.Arguments = #"\\" + serverName + #" -i C:\WINDOWS\notepad.exe";
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Process p = Process.Start(info);

Running an interactive program such as notepad.exe doesn't always open a visible window on the target PC. Try opening Task Manager on the target PC while you run the code and see if notepad.exe appears in the list of running processes.
I'd suggest trying to run psexec from the command line first before attempting to call it via code.
psexec \\serverName "notepad.exe"
You may also want to use the "interactive" flag so it can interact with the desktop on the target.
psexec \\serverName "notepad.exe" -i

Your UNC path does not look good.
After the string concatenation, it will look something like
"\\serverNameC:\WINDOWS\notepad.exe"
Try to print it out. See documentation about UNC on MSDN, and some examples here (or google about UNC Path)
If you have only the default shares, it should be something like
"\\serverName\C$\WINDOWS\notepad.exe"
OR psexec let you use a different notation, but you have to be careful with double quotes there
psexec \\serverName"c:\WINDOWS\notepad.exe"
Also, ensure that the "Server" service is running on the target machine.
PsExec starts an executable on a remote system and controls the input and output streams of the executable's process so that you can interact with the executable from the local system. PsExec does so by extracting from its executable image an embedded Windows service named Psexesvc and copying it to the Admin$ share of the remote system. PsExec then uses the Windows Service Control Manager API, which has a remote interface, to start the Psexesvc service on the remote system.
The Admin$ share is created and managed by the "Server" service, so you need it running for psexec to work (http://windowsitpro.com/systems-management/psexec).

Just to extend current version of answer.
There could be a problem of execution psexec due to OS policy, to enable remote control you need to modify registry:
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
You can check this: Remote UAC LocalAccountTokenFilterPolicy

Related

Process.Start in C# The system cannot find the file specified error

This is a silly and tricky issue that I am facing.
The below code works well (it launches Calculator):
ProcessStartInfo psStartInfo = new ProcessStartInfo();
psStartInfo.FileName = #"c:\windows\system32\calc.exe";
Process ps = Process.Start(psStartInfo);
However the below one for SoundRecorder does not work. It gives me "The system cannot find the file specified" error.
ProcessStartInfo psStartInfo = new ProcessStartInfo();
psStartInfo.FileName = #"c:\windows\system32\soundrecorder.exe";
Process ps = Process.Start(psStartInfo);
I am able to launch Sound Recorder by using Start -> Run -> "c:\windows\system32\soundrecorder.exe" command.
Any idea whats going wrong?
I am using C# in Visual Studio 2015 and using Windows 7 OS.
UPDATE 1: I tried a File.Exists check and it shows me MessageBox from the below code:
if (File.Exists(#"c:\windows\system32\soundrecorder.exe"))
{
ProcessStartInfo psStartInfo = new ProcessStartInfo();
psStartInfo.FileName = #"c:\windows\system32\soundrecorder.exe";
Process ps = Process.Start(psStartInfo);
}
else
{
MessageBox.Show("File not found");
}
Most likely your app is 32-bit, and in 64-bit Windows references to C:\Windows\System32 get transparently redirected to C:\Windows\SysWOW64 for 32-bit apps. calc.exe happens to exist in both places, while soundrecorder.exe exists in the true System32 only.
When you launch from Start / Run the parent process is the 64-bit explorer.exe so no redirection is done, and the 64-bit C:\Windows\System32\soundrecorder.exe is found and started.
From File System Redirector:
In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64.
[ EDIT ] From the same page:
32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32.
So the following would work to start soundrecorder.exe from the (real) C:\Windows\System32.
psStartInfo.FileName = #"C:\Windows\Sysnative\soundrecorder.exe";
Old thread but providing one more possible case
In my case i was using arguments inside Process.Start
System.Diagnostics.Process.Start("C:\\MyAppFolder\\MyApp.exe -silent");
I changed it to
ProcessStartInfo info = new ProcessStartInfo("C:\\MyAppFolder\\MyApp.exe");
info.Arguments = "-silent";
Process.Start(info)
Then it worked.
One more case, similar to Ranadheer Reddy's answer, but different enough to trip me up for awhile.
I was making a simple mistake. I had this:
ProcessStartInfo info = new ProcessStartInfo("C:\\MyAppFolder\\MyApp.exe ");
info.Arguments = "-silent";
Process.Start(info);
See that space after the end of the path to the app? Yeah. It doesn't like that. It will not find your file if you include that.
The solution was to remove the extraneous space. Then it worked.
This is an easy enough mistake to make if you're converting an app from starting processes by launching "cmd.exe /c MyApp.exe -silent" to running "MyApp.exe" directly instead, which is what I was doing. I hope recording my misfortune here will help future developers.

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.

Process Start in IIS

Want to execute a exe within Application directory, in Dev system it works fine. In IIS, it is not executed, I have tried below points:
set default application pool to local system
set defualtpool, NETWORK_SERVICE, Everyone access to exe
Enabled 32 bit application to application pool
Server Version : Windows Server 2012
IIS Version: IIS 8.0
Below is my code
p.StartInfo = new ProcessStartInfo();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "wkhtmltopdf\\wkhtmltopdf.exe";
string arg1 = "";
arg1 = "www.google.com" + " test.pdf";
p.StartInfo.Arguments = arg1;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.WaitForExit(60000);
p.Close();
p.Dispose();
Make sure that the location at which your pdf file is getting generated "everyone has access to it"
it seems you are trying to convert html data to pdf file on your iis server. Make sure IIS server can access the site which your are trying to convert "Check if you can access those site using IE on your IIS server as there could be proxy issues"
Consider to set the working path of your exe:
p.StartInfo.WorkingDirectory = System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "wkhtmltopdf";
Also check task manager if the exe is in memory.
Sometimes when a batch got a low level error open a prompt, and IIS do not capture it, so the process is freezed in memory.
Consider also the set a log in the exe in order to understand what goes wrong.
I had similar problem. Solved moving the exe in another folder outside IIS application. This folder should have execution rights.

Cannot run a batch file from a Windows service in Windows server 2003 OS

I am using the following code to run a batch file from C#. The following code is part of my windows service. This code works perfectly fine in Windows XP but when I deploy my windows service to Windows server 2003 OS it returns exit code 1 (failure). Does someone know what I am missing? Do I need to give some special permission to the windows service? The service is installed as a Local System service.
ProcessStartInfo psi = new ProcessStartInfo();
//specify the name and arguments to pass to the command prompt
psi.FileName = ConfigurationManager.AppSettings["BatchFilePath"];
psi.Arguments = fileName;
//Create new process and set the starting information
Process p = new Process();
p.StartInfo = psi;
//Set this so that you can tell when the process has completed
p.EnableRaisingEvents = true;
p.Start();
//wait until the process has completed
while (!p.HasExited)
{
System.Threading.Thread.Sleep(1000);
}
//check to see what the exit code was
if (p.ExitCode != 0)
{
logger.Write("Exit Code" + p.ExitCode);
}
My next set would be to try setting the service to run as the user you're logged in as when it works. That way you'll know whether it is something specific to the Network Service account that's stopping it working

Categories