Archive

Posts Tagged ‘.NETCF’

.NET: Limiting a Program to a Single Instance

March 12th, 2009 No comments

Windows Mobile comes with an internal instance counter that will switch to an already existing window if a program is started more than just once.

Windows CE is lacking such a feature, but it is relatively painless to implement using P/Invoke and events.

public class SingleInstance : IDisposable
{
    [DllImport( "Coredll.dll", SetLastError = true )]
    static extern IntPtr CreateEvent( IntPtr ptrAlwaysZero, bool bManualReset, bool bInitialState, string lpName );
 
    [DllImport( "Coredll.dll", SetLastError = true )]
    static extern int CloseHandle( IntPtr handle );
 
    private IntPtr Handle = IntPtr.Zero;
 
    public bool IsSingleInstance { get { return this.Handle != IntPtr.Zero; } }
 
    /// <summary>A running program is identified by an already existing event that is named the same as the executable path.</summary>
    public SingleInstance() : this( Assembly.GetExecutingAssembly().GetModules()[ 0 ].FullyQualifiedName ) { }
 
    /// <summary>Accepts a single string as a parameter.</summary>
    public SingleInstance( string sEventName )
    {
        this.Handle = CreateEvent( IntPtr.Zero, true, false, sEventName );
        if ( Marshal.GetLastWin32Error() != 0 )
            Dispose();
    }
 
    public void Dispose()
    {
        if ( this.Handle != IntPtr.Zero )
            CloseHandle( this.Handle );
        this.Handle = IntPtr.Zero;
    }
}

You should make use of this class as early in the program as possible, e.g.

static class Program
{
    [MTAThread]
    static void Main()
    {
        using ( SingleInstance si = new SingleInstance() )
            if ( si.IsSingleInstance )
                Application.Run();
    }
}

Use of the above code is not restricted to Windows Mobile though. You could also use this snippet for regular Windows programs, just remember to replace the dllimport for Coredll.dll to kernel32.dll.

Byte Array to Hex String in C# and Linq

February 18th, 2009 2 comments

Converting a byte array into a hexadecimal string is straight forward to do using a loop and a few lines of code. With Linq, it can be done more elegantly in a single line:

string s = String.Join( String.Empty, byte_array.Select( x => x.ToString( "X2" ) ).ToArray() );

Another one-liner without using Linq (also works on the framework 2.0):

string s = String.Join( String.Empty, Array.ConvertAll<byte, string>( byte_array, delegate( byte b ) { return b.ToString( "X2" ); } ) );

There is no Array.ConvertAll<>() in the .NET Compact Framework 2.0 however. But with a little help from the BitConverter class, a one-liner is still possible:

string s = BitConverter.ToString( byte_array ).Replace( "-", String.Empty );

Which one of the above is the most efficient? Most likely it does not matter, unless you are converting megabytes of data at once. Obviously, using Linq is the slowest option, it takes more than twice as long as Array.ConvertAll<>().
Using BitConverter.ToString() is the most efficient option, being about 8 times (!) as fast as Linq.

Finally, if you are interested in rolling your own function, here is a really fast one which can compete with the BitConverter class:

static readonly char[] hex = "0123456789ABCDEF".ToCharArray();
 
static string ByteToHexString( byte[] array )
{
    if ( array == null || array.Length < 1 )
        return String.Empty;
    char[] c = new char[ array.Length << 1 ];
    for ( int i = 0; i < array.Length; ++i )
    {
        byte b = array[ i ];
        c[ i << 1 ] = hex[ b >> 4 ];
        c[ ( i << 1 ) | 0x01 ] = hex[ ( b & 0x0F ) ];
    }
    return new string( c );
}