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);
Hide the console window from a console application
Go to the Application Properties and change Output Type from Console Application to Windows Application.
Or you can do it using a code below
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
And in main
const int SW_HIDE = 0;
const int SW_SHOW = 5;
var handle = GetConsoleWindow();
ShowWindow(handle, SW_HIDE); // To hide
ShowWindow(handle, SW_SHOW); // To show
Also, you can run you application as a service. In order to do this you should create a service - File->New Project->Visual C#->Windows->Windows Service. Then create a public method StartWork()
and add all you logic there. And call this method in OnStart()
.
protected override void OnStart(string[] args)
{
try
{
this.StartJobs();
}
catch (Exception ex)
{
// catching exception
}
}
public void StartWork()
{
// all the logic here
}
In main you should create this service and use System.ServiceProcess.ServiceBase.Run()
to run it as service or call StartWork()
to run it as console application.
static void Main(string[] args)
{
TestService = new TestService ();
#if DEBUG
TestService.StartWork()();
#else
System.ServiceProcess.ServiceBase.Run(TestService );
#endif
}
Hide Console Window in C# Console Application
Change the output type from Console Application to Windows Application. This can be done under Project -> Properties -> Application in Visual Studio:
How to hide a console application in C#
Compile it as a Windows Forms application. Then it won't display any UI, if you do not explicitly open any Windows.
How to run a C# console application with the console hidden
If you are using the ProcessStartInfo
class you can set the window style to hidden - in the case of console (not GUI) applications, you have to set CreateNoWindow to true
:
System.Diagnostics.ProcessStartInfo start =
new System.Diagnostics.ProcessStartInfo();
start.FileName = dir + @"\Myprocesstostart.exe";
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; //Hides GUI
start.CreateNoWindow = true; //Hides console
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
Related Topics
Why Use the 'Ref' Keyword When Passing an Object
Creating Wizards For Windows Forms in C#
How to Get C# Enum Description from Value
Convert a Bitmap into a Byte Array
Cast Generic≪Derived≫ to Generic≪Base≫
Compression/Decompression String With C#
.Net Process.Start Default Directory
How to Get an Htmlelement Value Inside Frames/Iframes
How to Write a Simple Html.Dropdownlistfor()
How to Loop Through All Enum Values in C#
How to Convert Epoch Time in C#
How to Cast Object of Type 'System.Dbnull' to Type 'System.String'
Deserializing Json to .Net Object Using Newtonsoft (Or Linq to Json Maybe)
How to Deserialize an Array of Values With a Fixed Schema to a Strongly Typed Data Class