Programming magic, glory, and juices.

C# WPF Singleton Application

January 8th, 2009


There are several tutorials out there for C# that show you how to make an application so that it can only have one instance. However most of the example code out there doesn’t do it properly or it uses the FindWindow function which is not the proper way to identify an application.

The code below basically registers a window message using your application’s GUID. Then it sends that message to all the open processes, seeing if any will respond to it. Processes that do respond to the window message that we registered, are ours, because we have code that also responds to our own window message. Once we identify that a window is ours, we then send a COPYDATA window message to it with the command line parameter that we want to pass to the instance of our application that is visible to the user.

Source Code:

public partial class App : Application
{
    private static Mutex SingleMutex;
    public static uint MessageId;

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        IntPtr Result;
        IntPtr SendOk;
        Win32.COPYDATASTRUCT CopyData;
        string[] Args;
        IntPtr CopyDataMem;
        bool AllowMultipleInstances = false;

        Args = Environment.GetCommandLineArgs();

        // TODO: Replace {00000000-0000-0000-0000-000000000000} with your application's GUID
        MessageId   = Win32.RegisterWindowMessage("{00000000-0000-0000-0000-000000000000}");
        SingleMutex = new Mutex(false, "AppName");

        if ((AllowMultipleInstances) || (!AllowMultipleInstances && SingleMutex.WaitOne(1, true)))
            {
            new Main();
            }
        else if (Args.Length > 1)
            {
            foreach (Process Proc in Process.GetProcesses())
                {
                SendOk = Win32.SendMessageTimeout(Proc.MainWindowHandle, MessageId, IntPtr.Zero, IntPtr.Zero,
                    Win32.SendMessageTimeoutFlags.SMTO_BLOCK | Win32.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
                    2000, out Result);

                if (SendOk == IntPtr.Zero)
                    continue;
                if ((uint)Result != MessageId)
                    continue;

                CopyDataMem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Win32.COPYDATASTRUCT)));

                CopyData.dwData = IntPtr.Zero;
                CopyData.cbData = Args[1].Length*2;
                CopyData.lpData = Marshal.StringToHGlobalUni(Args[1]);

                Marshal.StructureToPtr(CopyData, CopyDataMem, false);

                Win32.SendMessageTimeout(Proc.MainWindowHandle, Win32.WM_COPYDATA, IntPtr.Zero, CopyDataMem,
                    Win32.SendMessageTimeoutFlags.SMTO_BLOCK | Win32.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
                    5000, out Result);

                Marshal.FreeHGlobal(CopyData.lpData);
                Marshal.FreeHGlobal(CopyDataMem);
                }

            Shutdown(0);
            }
    }
}

/***********************************************************************/

public partial class Main : Window
{
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        HwndSource Source;

        Source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
        Source.AddHook(new HwndSourceHook(Window_Proc));
    }

    private IntPtr Window_Proc(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam, ref bool Handled)
    {
        Win32.COPYDATASTRUCT CopyData;
        string Path;

        if (Msg == Win32.WM_COPYDATA)
            {
            CopyData = (Win32.COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(Win32.COPYDATASTRUCT));
            Path = Marshal.PtrToStringUni(CopyData.lpData, CopyData.cbData / 2); 

            if (WindowState == WindowState.Minimized)
                {
                // Restore window from tray
                }

            // Do whatever we want with information

            Activate();
            Focus();
            }

        if (Msg == App.MessageId)
            {
            Handled = true;
            return new IntPtr(App.MessageId);
            }

        return IntPtr.Zero;
    }
}

/***********************************************************************/

public class Win32
{
    public const uint WM_COPYDATA = 0x004A;

    public struct COPYDATASTRUCT
    {
        public IntPtr dwData;
        public int    cbData;
        public IntPtr lpData;
    }

    [Flags]
    public enum SendMessageTimeoutFlags : uint
    {
        SMTO_NORMAL             = 0x0000,
        SMTO_BLOCK              = 0x0001,
        SMTO_ABORTIFHUNG        = 0x0002,
        SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
    }

    [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
    public static extern uint RegisterWindowMessage(string lpString);
    [DllImport("user32.dll")]
    public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam,
        SendMessageTimeoutFlags fuFlags, uint uTimeout, out IntPtr lpdwResult);
}

C# String Wildcard Comparsion

January 8th, 2009


Here are some string extensions that I use to compare wildcards. CompareWildcard compares only one wildcard (ie “*.txt”), while CompareWildcards compares multiple wildcards (ig “*.txt;*.zip;”).

Usage Example:

string Path = "c:\readme.txt"; 

if (Path.CompareWildcards("*.txt;*.zip;", true) == true)
    {
    // Path matches wildcard
    }

Source code:

public static bool CompareWildcards(this string WildString, string Mask, bool IgnoreCase)
{
    int i = 0;

    if (String.IsNullOrEmpty(Mask))
        return false;
    if (Mask == "*")
        return true;

    while (i != Mask.Length)
        {
        if (CompareWildcard(WildString, Mask.Substring(i), IgnoreCase))
            return true;

        while (i != Mask.Length && Mask[i] != ';')
            i += 1;

        if (i != Mask.Length && Mask[i] == ';')
            {
            i += 1;

            while (i != Mask.Length && Mask[i] == ' ')
                i += 1;
            }
        }

    return false;
}

public static bool CompareWildcard(this string WildString, string Mask, bool IgnoreCase)
{
    int i = 0, k = 0;

    while (k != WildString.Length)
        {
        switch (Mask[i])
            {
            case '*':

                if ((i + 1) == Mask.Length)
                    return true;

                while (k != WildString.Length)
                    {
                    if (CompareWildcard(WildString.Substring(k + 1), Mask.Substring(i + 1), IgnoreCase))
                        return true;

                    k += 1;
                    }

                return false;

            case '?':

                break;

            default:

                if (IgnoreCase == false && WildString[k] != Mask[i])
                    return false;
                if (IgnoreCase && Char.ToLower(WildString[k]) != Char.ToLower(Mask[i]))
                    return false;

                break;
            }

        i += 1;
        k += 1;
        }

    if (k == WildString.Length)
        {
        if (i == Mask.Length || Mask[i] == ';' || Mask[i] == '*')
            return true;
        }

    return false;
}

Please feel free to post fixes, and suggestions in the comments below.

C# Convert Hex String To/From Byte Array, FAST!

June 26th, 2008


I previously wrote about how to quickly convert a byte array to its hex representation and back again in C. Now I’ve converted the same source code to C#. Even though there is a built in method using String.Format, it is too slow.

Source Code:

public static string ByteArrayToHexString(byte[] Bytes)
{
    StringBuilder Result = new StringBuilder();
    string HexAlphabet = "0123456789ABCDEF";

    foreach (byte B in Bytes)
        {
        Result.Append(HexAlphabet[(int)(B >> 4)]);
        Result.Append(HexAlphabet[(int)(B & 0xF)]);
        }

    return Result.ToString();
}

public static byte[] HexStringToByteArray(string Hex)
{
    byte[] Bytes = new byte[Hex.Length / 2];
    int[] HexValue = new int[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x0D,
                                 0x0E, 0x0F };

    for (int x = 0, i = 0; i < Hex.Length; i += 2, x += 1)
        {
        Bytes[x] = (byte)(HexValue[Char.ToUpper(Hex[i + 0]) - '0'] << 4 |
                          HexValue[Char.ToUpper(Hex[i + 1]) - '0']);
    }

    return Bytes;
}

PropertyGrid Performance

December 14th, 2007


Recently, even as recently as today, I was stretching my C# programming legs for work. We had an application that I’ve been maintaining that would update the user interface with statistics every so often. What I noticed was that as the updates occured, the user interface would become less responsive. I tracked down the issue to the fact that we were using the PropertyGrid incorrectly. What we had before was something along the lines of:

public void Event_OnUpdate(Class Sender)
{
   PropertyGrid_ObjectInfo.SelectedObject = new ObjectInfo(Sender);
}

Where ObjectInfo is basically a property wrapper for the Sender object. The slow responsiveness of the user interface was due to the fact that the PropertyGrid had to reload the SelectedObject each time it updated which, I guess is expensive. To solve the problem I simply used the following code instead.

public void Event_OnUpdate(Class Sender)
{
   if(PropertyGrid_ObjectInfo.SelectedObject == null)
      PropertyGrid_ObjectInfo.SelectedObject = new ObjectInfo(Sender);
   else
      PropertyGrid_ObjectInfo.Refresh();
}

I hadn’t seen anybody on Google run across the same problem with the PropertyGrid performing slowly so I decided to blog it. And that is that.

Cleaner C# Code

March 15th, 2007


Aligned operators

There are several reasons why you would want you code to be cleaner..

1. It is easier to read.
2. It is easier to maintain.

Let’s take use the following Mz code as an example..

string Message = "Sending Order [";

Message += "OrderId: " + Order.ID;
Message += " Vendor: " + Vendor.Username;
Message += " Transaction: "	+ Receipt.TransactionId;

Message += "]";

Debug.Print(Message);

Looks kinda neat and clean, but it is still pretty ugly. We can make it a bit easier on our eyes if we do the following.

string Message;

Message  = "Sending Order [ ";

Message += " OrderId: "	+ Order.ID;
Message += " Vendor: "	+ Vendor.Username;
Message += " Transaction: "	+ Receipt.TransactionId;

Message += "]";

Debug.Print(Message);

Well structured code

A lot of C# programmers will declare there variables in the code where ever they want. This makes it difficult because..

1. It looks ugly.
2. More frequent variable name collision.
3. Poor code structure

C# developers don’t usually declare variables at the top of their code.. instead they declare them inline. Declaring them inline is a lot easier, but it can make things a lot messer. Take a look at a more simple example below.

StreamWriter Writer = new StreamWriter(Request.GetResponseStream());
Writer.Write(Data, 0, Data.Length);
Writer.Close();

Here, we have declaration and assignment occuring at the top of the function, making things still messy. We can clean it up like so..

StreamWriter Writer;

Writer = new StreamWriter(Request.GetResponseStream());
Writer.Write(Data, 0, Data.Length);
Writer.Close();

The word Writer is aligned three times. You can see that all the variables are declared up at the top and are separated by two empty lines. You know what variables are declared throughout the whole function, all you have to do is scroll up top. This helps curve name collision so that everything is peachy.