HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Minimize the console window to tray

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
minimizethetraywindowconsole

Problem

I have a small console application that runs a very long task and I would like to hide the console window when I click on the minimize button but keep a notify icon in the system tray so that I would know when the task is completed or something went wrong.

Well, I did a lot of research mostly here on SE and I came up with the following code:

```
using System;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace iTray
{
class Program
{

#region pInvoke

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

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

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

private struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public Point ptMinPosition;
public Point ptMaxPosition;
public Rectangle rcNormalPosition;
}

private enum ShowWindowCommands
{
Hide = 0,
Normal = 1,
ShowMinimized = 2,
Maximize = 3,
ShowMaximized = 3,
ShowNoActivate = 4,
Show = 5,
Minimize = 6,
ShowMinNoActive = 7,
ShowNA = 8,
Restore = 9,
ShowDefault = 10,
ForceMinimize = 11
}

[DllImport("user32.dll")]
private static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

private const uint SC_CLOSE = 0xF060;
private const uin

Solution

Instead of using an infinite loop, use a Timer and an event handler. You only get a 15ms resolution (actually, Wait and Sleep have the same resolution), but that should be plenty quick enough for your purposes. It'll use less CPU and free up the thread to do other work.

It would also be best to separate your DllImports out into a separate class. You'll see a lot of folks make it static, but I like to unit test my code, so I tend to use a pattern something like this.

public class MyWrapper : IMyWrapper
{
    public int Foo(...)
    {
        NativeFoo(...);
    }

    [DllImport("Library.dll", EntryPoiny = "Foo")]
    private static extern int NativeFoo(...);

}


Where the interface matches the public API of MyWrapper. This allows you to test your client code in isolation from the native library, which likely interacts with hardware/the OS.

Code Snippets

public class MyWrapper : IMyWrapper
{
    public int Foo(...)
    {
        NativeFoo(...);
    }

    [DllImport("Library.dll", EntryPoiny = "Foo")]
    private static extern int NativeFoo(...);

}

Context

StackExchange Code Review Q#127742, answer score: 3

Revisions (0)

No revisions yet.