the following code is to open a console application (which uses pdcurses for output, nothing special):
myProcess.StartInfo.FileName = "some.exe";
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.CreateNoWindow = false;
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.Start();
The Problem is that it opens the designated window but directly closes it (it's barely visible). Starting the program without RedirectStandardInput works. The problem is that it does not throw an exception nor any error-message. What is wrong with my code? How can I write input to the program? Thanks.
Is some.exe a console program?
You could try starting cmd.exe with the /K switch and pass your some.exe as the argument to it.
Related
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.
I'm attempting to print off a file generated in my application using the following code:
var psi = new ProcessStartInfo("Temp.txt");
psi.UseShellExecute = true;
psi.Verb = "print";
psi.CreateNoWindow = true;
var process = System.Diagnostics.Process.Start(psi);
This works, and sends the file to the printer as expected. However, in the process, an instance of notepad opens for naught but a second. This is an application meant to run in the background, so those windows popping up are incredibly distracting.
Adding pi.WindowStyle = ProcessWindowStyle.Hidden; before the final line of the above snippet does help marginally. But still causes a brief, small popup - which drags the user out of any fullscreen application they may be in at the time.
I'm trying to do execute an external .bat by pressing a button.
The intention is to call some XCOPY instructions. Therefore I execute "sync.bat" using Process.Start(startInfo).
The output of that .bat is redirected to my App and shown in a dialog box. My code waits until the external call has finished.
echo "Batch SYNC started."
pause
xcopy "e:\a\*" "e:\b\" /f /i /c /e /y
pause
echo "Batch SYNC finished."
OK:
When I build my program as "release" and start it within VisualStudio2013, everything works fine (I see the Results, have to press ENTER in the black window, files are copied).
FAIL:
When I start my app by double-click (in file-explorer or from the desktop) or a debug build within the VisualStudio, I see the ECHO and the PAUSE output, but the batch did not stop and I see no results from XCOPY. Seems as if the PAUSE and XCOPY are killed immediately.
I got no exception and no entry in Windows-log.
I have tried to make DEBUG and RELEASE configuration identical (with no success).
Does anybody have an idea what I may do to get this simple function work outside the IDE?
Here is the code of the function called when the button is pressed:
private void ProcessSync_bat()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.FileName = "sync.bat";
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.Arguments = "";
startInfo.ErrorDialog = true;
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
dlgFKSyncMessageBox.AddLine("----------sync.bat started-----------");
dlgSyncMessageBox.AddLine("===============Result================");
while (!exeProcess.StandardOutput.EndOfStream)
{
dlgSyncMessageBox.AddLine(exeProcess.StandardOutput.ReadLine());
}
dlgSyncMessageBox.AddLine("===============ERRORS================");
while (!exeProcess.StandardError.EndOfStream)
{
dlgSyncMessageBox.AddLine(exeProcess.StandardError.ReadLine());
}
exeProcess.WaitForExit();
}
}
catch (Exception exp)
{
dlgSyncMessageBox.AddLine("========EXCEPTION========");
}
}
Solution:
If I additionally set
startInfo.RedirectStandardInput = true;
then it works. I may redirect input from dialog window to the Process. Since I do not need any input for the intended XCOPY, this solution works for me without catching chars from the Dialog window and Forward to the process.
I can't see the logic, why I have to Redirect input too, but I'm glad that my Software now does what I need.
Before you say its a duplicate question, please let me explain (as I've read all similar threads).
My application has both of these settings:
procStartInfo.CreateNoWindow = true;
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
and is also has WindowsApplication as the output type.
The black window STILL comes up when I call a command line command. Is there anything else I can do to hide the window? It doesn't happen for all commands, XCOPY is a situation where it the black window does flash up. This only happens though when the destination I'm XCOPYing too already contains the file and it's prompting me if I want to replace it. Even if I pass in /Y it will still flash briefly.
I'm open to using vbscript if that will help, but any other ideas?
The client will call my executable and then pass in a command line command ie:
C:\MyProgram.exe start XCOPY c:\Test.txt c:\ProgramFiles\
Here's the full code of the application:
class Program
{
static void Main(string[] args)
{
string command = GetCommandLineArugments(args);
// /c tells cmd that we want it to execute the command that follows and then exit.
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = procStartInfo;
process.Start();
}
private static string GetCommandLineArugments(string[] args)
{
string retVal = string.Empty;
foreach (string arg in args)
retVal += " " + arg;
return retVal;
}
}
The problem is that you're using cmd.exe. Only its console window will be hidden, not the console window for the process you ask it to start. There's little point in using cmd.exe, unless you are trying to execute some of the commands it implements itself. Like COPY.
You can still suppress the window if you need cmd.exe, you'll have to use the /B option for Start. Type start /? at the command prompt to see options. Not that it helps, you can't use START COPY.
There's a specific quirk in xcopy.exe that might throw you off as well. It does not execute if you don't also redirect the input. It just fails to run without diagnostic.
i see that you are calling cmd and then passing the command as parameters. Instead call the command directly
e.g.
System.Diagnostics.ProcessStartInfo procStartInfo = new System.DiagnosticsProcessStartInfo("xcopy", "<sourcedir> <destdir> <other parameters>");
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
You can try adding
process.StartInfo.UseShellExecute = false;
to your process
If you are calling cmd.exe in your C# code and passing the commands to it via standard input.WriteLine and you don't want your CMD window to pop up every time you run your code, you can simply write this command:
test.StartInfo.FileName = "cmd.exe";
test.StartInfo.CreateNoWindow = true;
By setting create no window to false, we are running the command sent to the CMD in the background and the output is not being displayed to the user. By setting it to false, the CMD window pops up.
I had a similar task - It is possible to hide the window after creation via an API call.
(In your case you maybe need a helper thread.)
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
If you know the handle of the new Window you can call
ShowWindow(hWnd, 0);
0 hides the window, 1 shows the window
To get the handle of the Window take a look at:
pinvoke.net enumwindows(user32)
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());