简体   繁体   中英

How can I hide a console window?

Question: I have a console program that shouldn't be seen. (It resets IIS and deletes temp files.)

Right now I can manage to hide the window right after start like this:

static void Main(string[] args)
{
    var currentProcess = System.Diagnostics.Process.GetCurrentProcess();
    Console.WriteLine(currentProcess.MainWindowTitle);

    IntPtr hWnd = currentProcess.MainWindowHandle;//FindWindow(null, "Your console windows caption"); //put your console window caption here
    if (hWnd != IntPtr.Zero)
    {
        //Hide the window
        ShowWindow(hWnd, 0); // 0 = SW_HIDE
    }

The problem is this shows the window for a blink of a second. Is there any constructor for a console program, where I can hide the window before it is shown?

And second:

I use

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

and I don't like the 32 in it. Is there any way to do this without DllImport ?
A .NET way ?

If you don't need the console (eg for Console.WriteLine ) then change the applications build options to be a Windows application.

This changes a flag in the .exe header so Windows doesn't allocate a console session when the application starts.

If I understand your question, just create the console process manually and hide the console window:

Process process = new Process();
process.StartInfo.FileName = "Bogus.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;

I do this for an WPF app which executes a console app (in a background worker) and redirects standard output so you can display the result in a window if needed. Works a treat so let me know if you need to see more code (worker code, redirection, argument passing, etc.)

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeConsole();

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.I4)]int nStdHandle);

// see the comment below
private enum StdHandle
{
    StdIn = -10,
    StdOut = -11,
    StdErr = -12
};

void HideConsole()
{
    var ptr = GetStdHandle((int)StdHandle.StdOut);
    if (!CloseHandle(ptr))
        throw new Win32Exception();

    ptr = IntPtr.Zero;

    if (!FreeConsole())
        throw new Win32Exception();
}

See more console-related API calls here

    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    [DllImport("kernel32")]
    public static extern IntPtr GetConsoleWindow();
    [DllImport("Kernel32")]
    private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);

    static void Main(string[] args)
    {
        IntPtr hConsole = GetConsoleWindow();
        if (IntPtr.Zero != hConsole)
        {
            ShowWindow(hConsole, 0); 
        }
    }

This should do what your asking.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM