Process.Start doesn't start the process until main application is closed - c#

I have a WPF application. Clicking a button the application "starts" VLC using Process.Start() method. I tested this simple app on 2 computers:
public partial class MainWindow : Window
{
...
private void RunVlcButtonClick(object sender, RoutedEventArgs e)
{
string applicationFile = "vlc.exe";
MainWindow.RunProcess(applicationFile);
}
private static Process RunProcess(string applicationFile, string arguments = "")
{
Console.WriteLine($"Run process: {applicationFile} {arguments}");
Process process = MainWindow.GetProcess(applicationFile, arguments);
bool result = process.Start();
if (!result)
Console.WriteLine($"Can't start {applicationFile} {arguments}");
return process;
}
private static Process GetProcess(string applicationFile, string arguments)
{
ProcessStartInfo processStartInfo = new ProcessStartInfo(applicationFile, arguments);Process.StandardOutput StreamReader.
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.CreateNoWindow = true;
Process cmdProcess = new Process();
cmdProcess.StartInfo = processStartInfo;
cmdProcess.EnableRaisingEvents = true;
return cmdProcess;
}
}
As you can see this is nothing new or complicated. In the first computer works properly, but in the other one VLC instances are started when main application is closed.
The first computer is a Windows 10 Pro (build 16299) desktop.
The second computer is a Windows 10 Enterprise (build 10240) laptop.
Do you know why is this happening?

Related

c# start console application in win forms

I'm trying to make launcher for my games and I like to add music player in background, but if I start the process it instantly fail's.
Code
private void btnStartMusic_Click(object sender, EventArgs e)
{
ProcessStartInfo proc = new
ProcessStartInfo("MusicPlayer\\MemequickieMusicPlayer.exe");
proc.CreateNoWindow = true;
proc.WindowStyle = ProcessWindowStyle.Hidden;
proc.RedirectStandardError = false;
proc.RedirectStandardInput = false;
proc.RedirectStandardOutput = false;
proc.UseShellExecute = false;
Process.Start(proc);
}
Any Help is appreciated.
Try using the full path to the exe and setting the working directory; assuming the exe is in your executable folder:
string path = Path.Combine(Application.StartupPath, "MusicPlayer");
ProcessStartInfo proc = new
ProcessStartInfo(Path.Combine(path, "MemequickieMusicPlayer.exe"));
proc.WorkingDirectory = path;
If the error persists and you want to debug the output, change:
proc.RedirectStandardOutput = true;
Create the process like this:
Process process = new Process(proc);
process.Start();
while (!process.StandardOutput.EndOfStream) {
System.Diagnostics.Debug.Write(process.StandardOutput.ReadLine());
}
You should now see the output in your output window.

Close Console Window Upon Starting A New Build In Main

In main of my console application I am running an elevated version of my application if the user requests to run it elevated.
the code is doing this
elevated.exe myexe.exe //a /elevated
This code is being run in main so what happens when myexe is ran it opens a console window hits the code below and creates another console window with the new instance.
How do I close the initial window programmatically without closing the new one?
Environment.Exit(0) //closes the entire application THIS WONT WORK
enter code here
public void Run(string[] args) //myexe.exe
{
if (args[0] == "/elevated")
{
_command.RunElevated(path, arguments);
return;
}
}
Here is the meat of the RunElevated code pretty standard..
var process = new Process();
if (workingDirectory != null) process.StartInfo.WorkingDirectory = workingDirectory;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = fileName;
process.StartInfo.Arguments = arguments;
process.Start();
// deal with output
standardOutput = process.StandardOutput.ReadToEnd();
standardError = process.StandardError.ReadToEnd();
// wait til the process exits
process.WaitForExit();
int exitCode = process.ExitCode;
OK maybe I know what's going on now. When you use UseShellExecute = false, then the program runs in the same command window, which you are closing with Environment.Exit(0).
So change to this:
var process = new Process();
if (workingDirectory != null) process.StartInfo.WorkingDirectory = workingDirectory;
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = fileName;
process.StartInfo.Arguments = arguments;
process.Start();
Do no redirect output because 1) you can't with UseShellExecute=true, and 2) you are closing your main application anyway so why redirect things to an app that is exiting in a couple milliseconds.
With these changes you spawn your app in its own, hidden, window, then just Environment.Exit(0) your main application which will kill the non-elevated one but won't touch the process you spawned.
Here's an entirely working example:
using System;
using System.Diagnostics;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
if (args.Length > 0 && args[0] == "/elevated")
{
var process = new Process();
/*process.StartInfo.WorkingDirectory = */
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = false;
process.StartInfo.FileName = "ConsoleApplication4.exe";
process.StartInfo.Arguments = "startedThroughElevatedCodePath";
process.Start();
Environment.Exit(0);
}
if (args.Length > 0 && args[0] == "startedThroughElevatedCodePath")
{
Console.WriteLine("Hello from elevated");
}
else
{
Console.WriteLine("Hello from not elevated");
}
Console.Read();
}
}
}

How do i start a process in c# calling net.exe without having a window pop open?

I am starting a process to disconnect a network drive, but it always pops up a command prompt window. It just flashes by quickly and disappears, but i would like to configure it so the window doesn't open at all. Any ideas?
Here is the c# code I'm currently using:
private void btnDisconnectNetwork_Click(object sender, EventArgs e)
{
Process DisconnectDrive = new Process();
DisconnectDrive.StartInfo.FileName = "Net.exe";
DisconnectDrive.StartInfo.Arguments = #" Use /d Q:";
DisconnectDrive.StartInfo.CreateNoWindow = true;
DisconnectDrive.Start();
}
I believe the following will also work:
using System.Diagnostics;
namespace processexample {
class Program {
static void Main(string[] args) {
ProcessStartInfo si = new ProcessStartInfo();
si.CreateNoWindow = true;
si.UseShellExecute = false;
si.FileName = #"C:\Windows\System32\net.exe";
si.Arguments = #"/help";
Process p = new Process();
p.StartInfo = si;
p.Start();
}
}
}
You have to set the CreateNoWindow and UseShellExecute in StartInfo.

RedirectStandardIn Stops Output

I have a GUI that wraps a console application to improve user experience. I'm using the Process class to spin off the console executable. I want the console window to come up, and I will manually write abbreviated output to it. Then, once the executable is finished, the console window will close and control passes back to the GUI.
However, it is an interactive program, requiring me to redirect both StandardIn and StandardOut. The problem is that the very act of redirecting the input stops all output from coming to the console.
I've included all the output code as I had it, but commented out. As it is, a console window will open and the prompts will appear, waiting for user input. If I uncomment RedirectStandardIn, the window appears, but simply remains blank. Am I misunderstanding the role of Process.StandardInput?
class HandleExecutable
{
...
public void callExecutable(string executable, string args, string inputStr)
{
string commandLine = executable;
ProcessStartInfo psi = new ProcessStartInfo(commandLine);
psi.UseShellExecute = false;
psi.LoadUserProfile = false;
//psi.RedirectStandardOutput = true;
//psi.RedirectStandardError = true;
/* UNCOMMENT BELOW WILL CAUSE NO OUTPUT TO BE PUT TO THE CONSOLE */
//psi.RedirectStandardInput = true;
psi.WindowStyle = ProcessWindowStyle.Minimized;
psi.Arguments = args;
Process p = new Process();
p.StartInfo = psi;
try
{
p.Start();
//p.StandardInput.WriteLine(inputStr);
//p.BeginOutputReadLine();
//p.BeginErrorReadLine();
if (outputHandler != null) p.OutputDataReceived += outputHandler;
if (errorHandler != null) p.ErrorDataReceived += errorHandler;
p.WaitForExit();
p.Close();
p.Dispose();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
}
}

Asp.net CMD security problem

I am having trouble with permissions on Windows 2008 server. i have a command line utility that I need to run to convert some standard files to CSV files. That are in turn used to import data to my SQL database. I am able to get the done to work fine on my 2003 server but my windows 2008 server is not allowing the code to run. Below is a watered down version of the code. Basically in this example I am just trying to run a simple command. But I keep getting the output access denied. How do I correct this?
public partial class _Bank : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btn_Click(object sender, EventArgs e)
{
ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd.exe");
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.RedirectStandardError = true;
Process process = Process.Start(processStartInfo);
if (process != null)
{
process.StandardInput.WriteLine("dir");
process.StandardInput.Close();
string outputString = process.StandardOutput.ReadToEnd();
Response.Write(outputString);
string error = process.StandardError.ReadToEnd();
Response.Write(error);
}
}
private string ProcessRunner()
{
ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd.exe");
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.UseShellExecute = false;
Process process = Process.Start(processStartInfo);
if (process != null)
{
//process.StandardInput.WriteLine("This is a test line");
process.StandardInput.WriteLine("c:\\");
process.StandardInput.WriteLine("This is a test line");
process.StandardInput.Close(); // line added to stop process from hanging on ReadToEnd()
string outputString = process.StandardOutput.ReadToEnd();
Response.Write(outputString);
return outputString;
}
return string.Empty;
}
public static int ExecuteCommand(string Command, int Timeout)
{
int ExitCode;
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/C " + Command);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = false;
Process = Process.Start(ProcessInfo);
Process.WaitForExit(Timeout);
ExitCode = Process.ExitCode;
Process.Close();
return ExitCode;
}
}
This is running within an asp.net application with an App-Pool. The App-Pool has an identity (LocalSystem, Network Service etc) this process is executed.
Make sure that this user does have the necessary privileges on the folders you are planning to access.
IMHO: for security reasons starting another process within a web application is not best practice and should never be done on internet web applications.
EDIT:
Usualy the user is named ASPNET or IWAM_[Servername] (IWAM_... Built-in account for Internet Information Services to start out of process applications). Just give access to the folder to that user.

Categories

Resources