Running a CMD command from C# - c#

i am trying to run the following cmd command, that works on the CMD, from a C# console app but nothing happens:
string strCmdText = "\\office\\Public\\Tools\\myTool\\myTool_V1.0\\myTool.exe -kan tools -kdb Adhoc - ktn Components3 - uri https://coprime.osdinfra.net";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);
the cmd window is emmidiatly closed after pressing F5 in VS so i can't see the output of "myTool.exe" - which does in fact print status about its progress on the cmd when run from a cmd window.
Also the desired effect of the program doesn't happen so i know it didn't work.
Need help please

Command Prompt does not take a program in as an argument to start. However, I can't see a reason to use command prompt here. You're code is starting the process "Cmd.exe" so it can start another process. Why not eliminate the middle man and just start the process you want to start? Then you can pass the process' real arguments as arguments in process.start().
Update:
You can start a program from command prompt, but it's a specific command. It goes like this:
CMD.exe /c {string of commands to execute}
So for instance, you could run it through cmd if you need to by doing this:
string strCmdText = "/c start \\office\\Public\\Tools\\myTool\\myTool_V1.0\\myTool.exe -kan tools -kdb Adhoc - ktn Components3 - uri https://coprime.osdinfra.net";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);

Related

C# Started Command Prompt not closing

I just started using C# again and I encountered a bug/issue while trying to start a process using command prompt.
I am trying to start/open the default On-Screen Keyboard from windows using command prompt. However, after the osk.exe executed, The command prompt window is still open. After manually closing the command prompt window by clicking "x" button and tried to click the button to execute the code again, The command prompt will then close after opening osk.exe as it should be.
Here is the code I tried to run:
Process.Start(Path.Combine(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.System)).FullName, "Sysnative", "cmd.exe", "/c osk.exe ; exit");
I got this code from this website
I even tried to run another line just to kill all open command prompt with code below. But after executing, another command prompt is opened and never automatically closed....
System.Diagnostics.Process.Start("CMD.exe", "taskkill /IM cmd.exe");
I tried to manually run in command prompt just to see if my windows command prompt has bugs, but its working fine.
I just want to open on-screen keyboard when a button is clicked without keeping an open command prompt and without changing the platform type of my application (i tried to do this before and it messed up most of my OLEDB Connections).
Any answers and suggestions is highly appreciated.
Also, I'm very sorry for my bad English.
This should work, it doesn't start CMD though:
//specify full path - possible through environment variables
var psi = new ProcessStartInfo(#"c:\windows\system32\osk.exe");
psi.UseShellExecute = true;
var process = Process.Start(psi);

c# opens the batch file but doesn't execute the VBScript in the .bat

I'm developing an application in C#. The main idea is:
Press button
Open .bat file
The .bat file opens Telnet [IP] [Port]
.bat file executes the VBScript
VBScript writes some commands to the telnet window
When I run this batch file by double-clicking on it, it works fine. However, wen I try to run it from a C# app, it doesn't work.
I already tried many methods.
Here is a few examples about what I tried:
Is it possible to use a batch file to establish a telnet session, send a command and have the output written to a file?
C# Winforms and command line batch files
batch works fine but "windows cannot find devcon.exe" in c# program
When I tried this:
string cmd = #"path";
var m_command = new System.Diagnostics.Process();
m_command.StartInfo.FileName = #"file.bat";
m_command.StartInfo.Arguments = cmd;
m_command.Start();
I got the error:
windows cannot find .exe make sure you typed the name correctly and then try again
And when I tried this:
string cmd = #"path";
var m_command = new System.Diagnostics.Process();
m_command.StartInfo.FileName = #"file.bat";
m_command.StartInfo.Arguments = cmd;
m_command.Start();
It works, but just opens telnet, the VBScript doesn't works.
This is the code in the .bat file:
:: Open a Telnet window
start C:\Windows\System32\telnet.exe 192.168.0.198 49211
:: Run the script
cscript SendKeys.vbs
This is the code in the .svs file:
set OBJECT=WScript.CreateObject("WScript.Shell")
WScript.sleep 500
OBJECT.SendKeys "T{ENTER}"
WScript.sleep 1000
OBJECT.SendKeys "T{ENTER}"
OBJECT.SendKeys " "
I expect the .VBS to write the command to the telnet window, however when I click the button in c# form, it just opens telnet, the VBScript doesn't works.
What you could do is find the cscript.exe file and execute it directly,like this:
for /f "tokens=*" %%C in ('where csscript.exe') do (%%C Sendkeys.vbs&goto Next)
:Next
rem This is only necessary because we want to run the script once
This migth work, but as the commenters said,using sendkeys is really not recommended,because it can cause major problems, once the windows are set incorrectly, or some of the progresses get delayed.

Process.Start() does nothing

I have to start a VPN connection (Fortinet) by code.
I have a cmd file that establish the connection.
If I call the cmd file on the shell it works pretty fine.
When I call it via Process.Start it does nothing.
It doesn't throw any exception, it seems to execute but VPN does not connect.
On the standard output I can read the echo I put on the cmd file (so it is executing the right file).
I launched a ping -d to see when the vpn goes up, when I call it via shell it goes up in a few seconds, via C# it is not.
I also tried a sleep(30000) but nothing.
My cmd (ConnectFile.cmd):
#echo off
#echo Connecting to VPN
"C:\Program Files (x86)\Fortinet\SslvpnClient\FortiSSLVPNclient.exe" connect -s "vpn myvpn"
My code (connectFile and disconnectFile are strings that contain the full path of the cmd files):
try
{
var startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = connectFile;
startInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(connectFile) ?? "";
System.Diagnostics.Process process = System.Diagnostics.Process.Start(startInfo);
System.Threading.Thread.Sleep(30000);
base.GetFiles(folder);
}
finally
{
System.Diagnostics.Process.Start(disconnectFile);
}
You have to separate the parameters. FileName is for the exe file, not the whole shell command (you're explicitly saying not to use the shell). So put the parameters to the Arguments property in ProcessStartInfo.
In your case, the parameters should be:
FileName - C:\Program Files (x86)\Fortinet\SslvpnClient\FortiSSLVPNclient.exe (no quotes)
Arguments - connect -s "vpn myvpn" (again, no quoting)
Second, you have to read the standard output if you capture it. If the output buffer gets full before you read it, the called process will stop working - it has to wait for the buffer to be emptied. If you're sure the application will actually finish at some point, simply remove the Thread.Sleep and call ReadToEnd right away. Otherwise, use eg. asynchronous reading to get the data.
Also, it's usually a good idea to set WorkingDirectory. Even if the application doesn't need any data from the working directory, it's safer, since only admins can change Program Files - this helps against DLL inject hacks.

How does the command prompt know when to wait for exit?

I was attempting to do a Windows command prompt re-code in C#. I was wondering how the command prompt knows when to wait for the process started to exit, and when not to wait for the called process to exit.
For example, if you type in the command prompt "notepad", Notepad will launch, but you can still execute other commands. However, if you open a utility such as more.com, ping.exe, or another utility, it will wait for the executing program to finish before letting you execute another command.
How does the command prompt know when to wait for exit, and how can this behavior be emulated in C#?
If the application is a Win32 GUI application, it will just run and command prompt won't wait for it to exit.
If the application is a console application, it will run in the command prompt and you'll need to wait for it to finish to get the command prompt back.
EDIT:
OK. It seems you need technical explanation. If you want to emulate the same feature in your application, you can check IMAGE_OPTIONAL_HEADER of EXE files here.
Inside IMAGE_OPTIONAL_HEADER, there is:
WORD Subsystem;
If SubSystem == 0x02 it means it's a GUI application.
If SubSystem == 0x03 it means it's a command prompt app.
EDIT 2:
If you want to see it in action:
Download http://www.ntcore.com/exsuite.php
Copy calc.exe or notepad.exe to your desktop
Open copied calc.exe in CFF Explorer
Navigate to Nt Headers -> Optional Headers
Change SubSystem from 0x002 to 0x003
Save it
Now run the new modified calc and you'll see the command prompt wait for it to be terminated.
The default from a command prompt is to spawn the GUI program in a separate process/fork.
However, you can run notepad (or other GUI program) inline with your command prompt / shell script:
start /w notepad.exe
This way, the command prompt / shell script only continues after the notepad.exe process has terminated.
Hope this helps, TW
When you start a new process, a GUI application in this context that actually works outside the boundaries of the prompt, the prompt will not wait. But, if you run a command that works entirely under the boundaries of the current instance of a prompt, it waits.
So, command notepad just starts the Notepad application and leaves control of application. While, command ipconfig runs under a domain (no this is not application domain), of the prompt.
To extremely generalize, when you use Process.Start in your C# equivalent, do not wait. It anyway will not.

issue in executing commands in cmd using C#

I am doing two commands in cmd from C# application.
renaming a file
string commandToExecute;
commandToExecute = #"/c ren E:\filename filename.rar";
Process.Start("cmd.exe", commandToExecute);
unrar-ing a file
commandToExecute = #"/c unrar e E:\filename.rar";
Process.Start("cmd.exe", commandToExecute);
The first part of the code works, but the second part doesn't, although it is working when I write the command in cmd manually. And I noticed that when executing in C# it runs the application itself again (like recursion). I don't know why.
Note: I am using 64-bit windows 7.
Remember that Process.Start launches another process. If the commands need to run serially, you need to obtain a Process object from Process.Start and call the WaitForExit method.

Categories

Resources