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
How to Check Whether a String Is a Valid Http Url
Linq - Left Join, Group By, and Count
Upload and Download a File To/From Ftp Server in C#/.Net
ASP.NET MVC Binding to a Dictionary
How to Delete All Files and Folders in a Directory
How to Set Processor Affinity to a Thread or a Task in .Net
Efficient Way to Remove All Whitespace from String
Detecting Usb Drive Insertion and Removal Using Windows Service and C#
What Is the Correct Way to Use JSON.Net to Parse Stream of JSON Objects
Call One Constructor from Another
Httpwebrequest Using Basic Authentication
ASP.NET MVC Conditional Validation
Wpf Binding UI Events to Commands in Viewmodel
Unauthorizedaccessexception Cannot Resolve Directory.Getfiles Failure
Why Can't I Use the 'Await' Operator Within the Body of a Lock Statement