Writing a pure SysTray Application without a Window

One nice day I had to implement a pure SysTray application. The application should stay in SysTray with a notification icon, but without a main window. So my first thought was to hide the application window within the OnLoad(). At this point my adventure started.

I really fast came to the conclusion that it's not possible to hide a main window by setting the visibility to false. So what to do. I was searching with google and found some hints like set the window size to 1,1 or opacity to 0% and so on. The best idea was to call a native Windows API which hides the window. Cruel … All this solutions operated as a workaround but did not solve the problem.

So I did some research and found a solution which works without having such cruel workarounds.

The idea is not to create a window and to hide it. You create your own application context which simply consists of a notification icon without a window. So you don't have to hide it, because it's not existend.

///
/// New Context class derived from the application context
///
public class SysTrayContext: ApplicationContext
{
    private SysTrayNotification notification;

    #region STA Thread

    ///
    /// Start Thread and run the new sys tray context
    ///
    [STAThread]
    private static void Main()
    {
        Application.Run(new SysTrayContext());
    }

    #endregion

    ///
    /// Initializes a new instance of the class.
    ///
    public SysTrayContext()
    {
        notification = new SysTrayNotification();
        notification.Visible = true;
    }
}

The SysTrayNotification class does only contain a simple NotificationIcon and a ContextMenu. So it's easy to implement.

///
/// Initializes a new instance of the class.
///
public SysTrayNotification ()
{
    /*
     * Set the systray icon
     */
    Assembly thisExe = Assembly.GetExecutingAssembly();
    Stream iconStream = thisExe.GetManifestResourceStream(NTSVC);
    notifyIcon.Icon = new System.Drawing.Icon(iconStream);

    /*
     * Create the context menu
     */
    menu.MenuItems.Add("&Say hello world", new EventHandler(SayHello) );
    menu.MenuItems.Add("-");
    menu.MenuItems.Add("&Close", new EventHandler(OnClose));

    notifyIcon.ContextMenu = menu;
}

As you can see you don’t have to care for hiding the main application window – because you don’t have any.

The whole example can be downloaded from:
Writing a pure SysTray Application without a window.

Framework for Console Applications, or how to parse command line arguments.

Sometimes developers have to implement stupid things. One of this stupid things is parsing command line arguments that are used by a console application. That’s where my story begins.

Last time I had to implement such an algorithm for the thousandths time. One time too much. So I decided to write a framework which does the command line argument parsing for me. During my development I found out that there exists 3 different command line argument types.

Look at the definition of the DIR command in DOS.

DIR [directory] [/A:attributes] [/B] [/L] ...

Anonym argument: The parameter [directory] is an anonym argument, because it has no name and it’s always defined as the first parameter.

Argument: The [/A:attributes] parameter is an argument, because it has a name [A] and a value [attributes].

Command: The [/B] and [/L] parameter is a command, because it has a name, but no value.

The problem was now to prevent the SWITCH/CASE hell and to provide a simple API which can handle these 3 parameter types. The result of my research is a base class named 'CommandLine' that offers a few methods like AddArgument, AddCommandand AnonymArgument.

The handling of the command line parameters is based on Delegates which will be dynamically invoked when parsing the arguments by the CommandLine Base class.

I made a small Dir command rebuild. Here’s the command definition.

Code within the constructor
AnonymArgument = new Argument(new ArgumentDelegate(SetDir), "Directory to show.");
AddCommand ("?", new CommandDelegate(ShowHelp), "/?\tShows the parameters help.");
AddArgument ("A", new ArgumentDelegate(SetAttributes), setAttributeHelp);

The methods SetDir, ShowHelp and SetAttributes are invoked dynamically by the base class. So you only have to define the delegate methods.

Delegate method definition
private void SetAttributes (string content) { ... }
private void SetDir (string content) { ... }
private void ShowHelp () { ... }

With this functionality you are able to write console applications quite fast and you can invest your time in more relevant programming parts.

For a better re-use of the component I placed the common part in a separate assembly named AdFactum.CommandLine.dll.

The whole example can be downloaded using the following link:
CommandLine Framework