Process.Start, Batch files and Quoting - c#

I wrote a BAT script that automatically connects and disconnects a broad band connection:
netsh mbn connect interface="Mobile Broadband Connection" connmode=name name="My Provider"
netsh mbn disconnect interface="Mobile Broadband Connection"
When I click the BAT script it is working fine, but when I execute it with Process.Start:
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c reconnect.bat",
WindowStyle = ProcessWindowStyle.Minimized,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
var process = new Process
{
StartInfo = startInfo
};
process.Start();
netsh returns an error that the mbn command was not found.
Before I was using a BAT file I started the commands directly. They worked fine on the shell, but got the same error when using Process.Start.
Why is this happening to me?
Output:
C:\Dev\NetworkAdapterTest\NetworkAdapterTest\bin\Debug>netsh
mbn connect interface=\"Mobile
Breitbandverbindung\" connmode=name
name=\"A1 2\" The following command
was not found: mbn connect
interface="Mobile Breitbandverbindung"
connmode=name name="A1 2".
C:\Dev\NetworkAdapterTest\NetworkAdapterTest\bin\Debug>netsh
mbn disconnect interface=\"Mobile
Breitbandverbindung\" The following
command was not found: mbn disconnect
interface="Mobile Breitbandverbindung"
Notice how the quoting is really wired. I got the same issues when I started the commands directly.
When I compile the solution with Visual Studio 2008 everything is working as intended.
Question is no longer relevant.

The content of your arguments variable doesn't seem to make a lot of sense. If your program is located in "C:\Temp", it will be: "C:\Temp\/c reconnect.bat".
If the bat file is in the same folder as your application, you might want to use this code:
var arguments = string.Format("/c \"{0}\"",
Path.Combine(Application.StartupPath, "reconnect.bat"));
The extra quotes, in case your path has spaces in it.

Instead of using "cmd.exe", have you tried starting the batch file directly? It should work without having to go through cmd.exe.
The other thing I would check is that you're using the correct path. The easiest way is to have the Bat in the same directory as your executable, or refer to the full path in the filename.
Stack Overflow - how to execute a batch file from windows form

Related

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

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

Process.Start(); as another user works but explorer.exe iexplore.exe throws exception

I'm having problems with a program and its buttons (I know, I'm awesome lol) the buttons can be "programmed" to run programs. They also can be set to run as admin (different credentials).
If I set up simply notepad or cmd or explorer it runs like charm. But if I start iexplore it has got no admin rights.
I had problems before with running explorer.exe the solution was that I had to run it by typing the full path C:\windows\explorer.exe to be able to run it but that I solved it by setting up the VB2015 compiler (?) to Platform target: x64.
My other problem is that if I try to run dsa.msc or generally anything ends with msc it throws the following exception, even if I set up the full path to the syswow64 (or the system32) folder like c:\windows\syswow64\dsa.msc
"The specified executable is not a valid application for this OS platform."
Running the C:\Windows\System32\mmc.exe "services.msc" (or syswow64, with or without the /computer= switch) throws
"The requested operation requires elevation." which I have since I'm able to run services.msc (and all other msc-s from command line with the same user rights)
Thank you.
A beginner.
Basically you don't need to run the host app as administrator! There is a variable (inside your Process instance) called StartInfo (which is an instance of the ProcessStartInfo Class), where Verbs could be used as followed:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("E:\\Users\\Temp\\app.exe")
{
Verb = "runas"
}
};
p.Start();
This will prompt the user to run the app.exe as administrator.
Edit
Running a Process as a defined user:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("E:\\Users\\Temp\\app.exe")
{
Verb = "runas",
Arguments = "/user:Vira"
}
};
For more information about those RUNAS Arguments, click me! :)

run a program using c# return error?

I am broad-casting using c# OBS open broadcaster I am passing parameters of my live stream like API's key, url know problem is that here is my code
ProcessStartInfo info = new ProcessStartInfo("//mysoftware//obs.exe" , "rtms://334.5.55.55/live 34534-4354-5646-45645");
Process.Start(info);
when i locally pass the path to win explorer windows. It returns the same error as returned by program but a unique scenario when i write the same path in run.exe and along with parameters and then click ok it runs the software.
What the problem the error is
failed to find locale /en-us.ini file
but program works correctly when i double click on its .exe
but remember i have copy pasted my software in debug folder that is working correctly there.
To open OBS from the bash you will need first move to the path in which is obs.exe and then execute obs:
cd path/to/obs/
obs.exe
To achieve this by using C# you can do the following:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = "path/to/obs/"; // like cd path command
startInfo.FileName = "obs64.exe";
Process.Start(startInfo);

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.

C# executing python script through cmd fails due to insufficient permissions

I'm attempting to run a command, similar to shell command, to execute a python script which saves a file by starting a Process
Process proc = new Process {
StartInfo = new ProcessStartInfo {
FileName = "cmd.exe",
Arguments = "/c python c:\\test\\script.py",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
I need to be able to get the standard output back to my c# program, and had to set UseShellExecute to false.
The python script is being executed and I'm getting the output back, but the script isn't getting the permissions to save the file to a folder in the disk. The same file I'm able to save in the c# code.
Is there any way to give the same permissions to the python script as the c# code which executes it.
Strangely, the issue I'm facing is not reproducible on my local machine and only on a windows-server environment.

Categories