Hide Console Window from Process.Start C#

How can i start process and hide it's window?

Add the following somewhere in your code

[DllImport("user32.dll")]
private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);

And then try starting the browser using the following:

        var process = new Process
{
StartInfo =
{
FileName = "firefox.exe",
Arguments = "http://stackoverflow.com/",
CreateNoWindow = true,
ErrorDialog = false,
WindowStyle = ProcessWindowStyle.Hidden
}
};
process.Start();
Thread.Sleep(1000);
ShowWindow(process.MainWindowHandle, 0);

Hiding the Console Window When Running Process as a User with DllImports

The only way of doing this I could find that actually worked is by running the commands via a remote PowerShell session as a user who has full domain access:

static class Ps
{
private const string RemoteHost = "ADMINSERVER.DOMAIN1.co.uk";
private static string _errors;

/// <summary>
/// Executes the given command over a remote powershell session
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static Collection<PSObject> RemoteCommand(string args)
{
SupportMi.Trace = $"Remote Command({args}) {{";

var script = BuildScript(args);
var results = Execute(script);

SupportMi.Trace = $"RES: {results[0]} ERR: {_errors} }}";
return results;
}

/// <summary>
/// Takes a complete script and executes it over a powershell Runspace. In this case it is being
/// sent to the server, and the results of the execution are checked for any errors.
/// </summary>
/// <param name="script"></param>
/// <returns></returns>
private static Collection<PSObject> Execute(string script)
{
var results = new Collection<PSObject>();

// Using a runspace
using (var runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();

using (var pipeline = runspace.CreatePipeline())
{
pipeline.Commands.AddScript(script);

try
{
results = pipeline.Invoke();
var errors = pipeline.Error.Read(pipeline.Error.Count);
foreach (var error in errors)
{
_errors += error;
}
}
catch (Exception ex)
{
results.Add(new PSObject(ex.Message));
SupportMi.Trace = ex.Message;
}
}
}

return results;
}

/// <summary>
/// Takes a string argument to be sent to the remote powershell session and arranges it in the correct format,
/// ready to be sent to the server.
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
private static string BuildScript(string args)
{
// Build the script
var script = Creds() + Environment.NewLine +
$"Invoke-Command -session $sessions -ScriptBlock {{ {args} /U DOMAIN1\\adminusername /P adminpassword }}" + Environment.NewLine +
"Remove-PSSession -Session $sessions" + Environment.NewLine +
"exit";

return script;
}

/// <summary>
/// Returns the credentials for a remote PowerShell session in the form
/// of a few lines of PowerShell script.
/// </summary>
/// <returns></returns>
private static string Creds()
{
return "$pw = convertto-securestring -AsPlainText -Force -String \"adminpassword\"" + Environment.NewLine +
"$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist \"DOMAIN1\\adminusername\",$pw" + Environment.NewLine +
$"$sessions = New-PSSession -ComputerName {RemoteHost} -credential $cred";
}
}

So to maintain a console-less action we can call the RemoteCommand method and pass in the command we want to send. RemoteCommand will first build our query/command using BuildScript and Creds (for the admin credentials).

This is then sent to the Execute method, which creates a new PowerShell RunSpace, which can run the command.

Some caveats of using this method :

  • The app must be run on the domain on which the "admin" server exists
  • There must exist an admin account which has access to any machine which wishes to run this code as well as the server (in this case, ADMINSERVER)
  • Any errors will exist on the remote server, so we must take care to handle these properly so that they are passed back into our application

Show/Hide the console window of a C# console application

Here’s how:

using System.Runtime.InteropServices;

[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

const int SW_HIDE = 0;
const int SW_SHOW = 5;

var handle = GetConsoleWindow();

// Hide
ShowWindow(handle, SW_HIDE);

// Show
ShowWindow(handle, SW_SHOW);

How do I hide a console application user interface when using Process.Start?

        Process p = new Process();
StreamReader sr;
StreamReader se;
StreamWriter sw;

ProcessStartInfo psi = new ProcessStartInfo(@"bar.exe");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
psi.CreateNoWindow = true;
p.StartInfo = psi;
p.Start();

This will start a child process without displaying the console window, and will allow the capturing of the StandardOutput, etc.



Related Topics



Leave a reply



Submit