Windows 8 Developer Preview on VMware Workstation

Since I heard that Microsoft Windows 8 Developer Preview became available for anyone to download (and given the fact it was catered to developers!), I felt I had no reason not to download it.  I've had VMware Workstation installed for quite some time and was totally worth the price I paid for it, even if my employer didn't provide it.  I figured I'd fire it up and mount the ISO in a new 64-bit virtual machine.

What I very quickly got was a "HAL_INITIALIZATION_FAILED" error.  Is this the new style for the blue screen of death?

Your PC ran into a problem that it couldn't handle, and now it needs to restart. You can search for the error online: HAL_INITIALIZATION_FAILED
Your PC ran into a problem that it couldn't handle, and now it needs to restart. You can search for the error online: HAL_INITIALIZATION_FAILED

Perhaps not-so-coincidentally, VMware just today released version 8.0.0 build 471780, so I tried installing that on top of my older version 7.1, and it worked.  If you're getting the HAL_INITIALIZATION_FAILED error message when booting up on a virtual PC, I'd recommend updating your VMware Workstation, since this worked for me.

Windows 8 setup began in much the same way that Windows 7 installed, which makes sense since Windows 8 is built off the 7 code base.  In fact, as far as system requirements go, it's supposed to work on anything that can run Windows 7.  Obviously there'd be some functionality that may not work on older hardware, but I appreciate the prospect of not having to buy a new PC.

It comes pre-loaded with Visual Studio 11 Express, containing templates for JavaScript, Visual Basic, Visual C#, and Visual C++ out of the box, all geared toward the "Windows Metro Style," what looks like a flat theme with multicolored boxes.  You'll find this instead of a traditional Start menu.

It's also got Expression Blend 5 Developer Preview for the more visually-inclined developers and designers.  Again it has the Metro Style layouts such as "Fixed Layout Application", "Grid Application", "Navigation Application", and "Split Application".  I can't wait to get into each of those.

Windows 8 Developer Preview already looks quite polished and I'm getting anxious to start digging into the various new capabilities.  And did I mention the new Task Manager?

 

 

VMware Workstation 8 – Your On-Ramp to the Cloud

Optional Parameters in C# 4.0

As a C# developer who has done a fair amount of coding in VB.NET too, I've wanted to use optional parameters for some of my overloaded methods long before the capability existed.  Fortunately, optional parameters finally do exist in C# .NET 4.0.

Prior to .NET 4, something like the following needed to be done to effectively allow optional parameters by essentially overloading the same method name multiple times, with a different number of parameters in each signature:

class OptionalParametersTest
{
	public void SomeMethod(string a)
	{
		SomeMethod(a, "default value", "default value");
	}

	public void SomeMethod(string a, string b)
	{
		SomeMethod(a, b, "default value");
	}

	public void SomeMethod(string a, string b, string c)
	{
		Console.WriteLine(string.Format("a: {0}, b: {1}, c: {2}", a, b, c));
		// Additional code here
	}
}

Here's a sample invoking each of these three overloaded methods:

var optionalParametersTest = new OptionalParametersTest();

optionalParametersTest.SomeMethod("1");
optionalParametersTest.SomeMethod("1", "2");
optionalParametersTest.SomeMethod("1", "2", "3");

This will output:

a: 1, b: default value, c: default value
a: 1, b: 2, c: default value
a: 1, b: 2, c: 3

Here's the same class in the first listing, OptionalParametersTest, but rewritten using optional parameters:

class OptionalParametersTest
{
	public void SomeMethod(string a, string b = "default value", string c = "default value")
	{
		Console.WriteLine(string.Format("a: {0}, b: {1}, c: {2}", a, b, c));
		// Additional code here
	}
}

The output is exactly the same:

a: 1, b: default value, c: default value
a: 1, b: 2, c: default value
a: 1, b: 2, c: 3

The notation, adding " = default value" after the name of the parameter, is familiar to VB.NET developers too.  And, just like in VB.NET, optional parameters must be defined last; you can't make the first parameter optional if the next one isn't.

But what if you want the second parameter (optional) to remain optional but define the third (also optional) parameter?  How can you get the following result?

a: 1, b: default value, c: 3

The trick is to omit the second parameter and define the third with a colon:

optionalParametersTest.SomeMethod("1", c : "3");

In the above line, we didn't bother specifying the parameter named "b" and instead just indicated that we wanted to define parameter "c".  This instructed the method to use the default value of "b" while still allowing the "c" parameter to be passed in.

Man, there are so many times I wished I could have done this before C# 4.0 hit the scene.

Interprocess Communication With Memory-Mapped Files, Part 3

I wasn't intending to write a third piece on this, but after spending more time with the prototype from the previous post, I realized that we've got a little more redundant code than I typically like to see.  While it's still fresh, I'd like to take the time to clean up the code, making the whole thing more reusable and much easier to extend later if needed.

To recap one last time, we had written two separate applications:

  • ConsoleAppListener
    Responsible for performing work and shutting down gracefully when it receives a “shutdown” message, after it has finished processing a full unit of work.  Multiple instances can exist, but each has a different “unique name” and a separate ConsoleAppController responsible for starting and monitoring each instance.
  • ConsoleAppController
    Responsible for starting ConsoleAppListener, ensuring it stays running, and sending a “shutdown” message instructing the ConsoleAppListener to shutdown gracefully when it’s finished processing.  Multiple instances can exist, but each is responsible for monitoring a ConsoleAppListener with a different “unique name”.
In the previous post, both ConsoleAppListener and ConsoleAppController reused two crucial functions, which I've wrapped into reusable methods, BroadcastMessage and GetMessage:
private void BroadcastMessage(int message)
{
	_memoryMappedFile = MemoryMappedFile.CreateOrOpen(_memoryMappedFileName, MessageByteSize);

	using (var accessor = _memoryMappedFile.CreateViewAccessor(0, MessageByteSize))
	{
		accessor.Write(0, message);
	}
}

private int GetMessage()
{
	int messageReceived;

	using (var stream = _memoryMappedFile.CreateViewStream())
	{
		var reader = new BinaryReader(stream);
		messageReceived = reader.ReadInt32();
	}

	Console.WriteLine(string.Format("Broadcast '{0}' received", messageReceived));

	return messageReceived;
}

In addition, I found it was best to encapsulate this communication code into a single class that's common to both classes.  The recurring theme is to make each class do just one thing, and do it well.  For this reason I've created a new project, called "Shared", and wrapped all of the communication logic into one class called InterprocessCommunicator.  This class is referenced by both projects and contains both the BroadcastMessage() and GetMessage() methods.

I've also refactored the other two classes to offload their communication work to the new InterprocessCommunicator, resulting in less redundant and cleaner code.
Project ConsoleAppController\Program.cs:
// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Diagnostics;
using System.IO;
using Shared;

namespace ConsoleAppController
{
    /// <summary>
    /// Responsible for launching a ConsoleAppListener process with a specific instance name and monitor it,
    /// if one isn't already running. If a ConsoleAppListener is already running, it will begin monitoring.
    /// If the ConsoleAppListener shuts down, this will restart it.
    /// If the user presses any key, the ConsoleAppListener is instructed to shut down gracefully.
    /// </summary>
    class Program
    {
        private const string ClientAppInstanceName = "SampleApp";
        private const string ClientProcessFileName = @"C:\Code\Personal\InterprocessCommunication\ConsoleAppListener\bin\Debug\ConsoleAppListener.exe";

        private static bool _isClientProcessRunning;
        private static bool _isShuttingDown;

        private static readonly InterprocessCommunicator InterprocessCommunicator = new InterprocessCommunicator(ClientAppInstanceName);

        static void Main(string[] args)
        {
            // Determine whether the client process is already running:
            _isClientProcessRunning = InterprocessCommunicator.LocateClient();
            if (_isClientProcessRunning)
            {
                InterprocessCommunicator.ProcessExited += ProcessExited;
                Console.WriteLine("Process already running");
            }
            else
            {
                // Launch the process:
                LaunchProcess();
                Console.WriteLine("Process launched");
            }

            Console.WriteLine("Hit any key to send shutdown message (at any time)");
            Console.ReadKey();

            WantProcessToShutDown();
            Console.WriteLine("Sent message to shut down");

            _isShuttingDown = true;
            Console.WriteLine("Hit Enter to close");
            Console.ReadLine();
        }

        private static void LaunchProcess()
        {
            var process = new Process();

            // Create process to launch the desired application:
            var processProperties = new ProcessStartInfo
                                        {
                                            UseShellExecute = true,
                                            WorkingDirectory = Directory.GetParent(ClientProcessFileName).FullName,
                                            FileName = ClientProcessFileName,
                                            Arguments = ClientAppInstanceName,  // Pass in the application's unique name
                                            RedirectStandardOutput = false
                                        };

            Console.WriteLine(String.Format("Launching executable: {0} {1} ", processProperties.FileName,
                                      processProperties.Arguments));

            process.StartInfo = processProperties;
            process.EnableRaisingEvents = true;
            process.Exited += ProcessExited;
            process.Start();
            _isClientProcessRunning = true;
        }

        private static void ProcessExited(object sender, EventArgs e)
        {
            Console.WriteLine("Process exited");
            _isClientProcessRunning = false;

            // Start up the process again:
            if (!_isShuttingDown)
            {
                LaunchProcess();
            }
        }

        private static void WantProcessToShutDown()
        {
            if (!_isClientProcessRunning)
            {
                return;
            }

            InterprocessCommunicator.BroadcastShutdownMessage();
        }
    }
}

Project ConsoleAppListener\Program.cs:

// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Threading;
using Shared;

namespace ConsoleAppListener
{
    /// <summary>
    /// Responsible for performing a unit of work ("processing") at a time,
    /// checking for a message to shutdown between processing.
    /// </summary>
    class Program
    {
        private static string _instanceName;
        private static InterprocessCommunicator _interprocessCommunicator;

        static void Main(string[] args)
        {
            // Get the unique name of this application from the first commandline argument:
            _instanceName = args.Length > 0 ? args[0] : string.Empty;

            if (string.IsNullOrEmpty(_instanceName))
            {
                Console.WriteLine("Error: Expected a unique name for the application from the command line.");
                Console.Read();
                return;
            }

            _interprocessCommunicator = new InterprocessCommunicator(_instanceName);
            _interprocessCommunicator.BroadcastProcessId();

            while (!ShouldClose())
            {
                Console.WriteLine("Close message not received, beginning to process");

                // Perform a unit of work:
                PerformProcessing();

                Console.WriteLine("Processing finished");
            }

            Console.WriteLine("Close message received. Hit Enter to close");
            Console.Read();
        }

        private static bool ShouldClose()
        {
            return _interprocessCommunicator.CheckForShutdownMessage();
        }

        static void PerformProcessing()
        {
            Console.WriteLine("Performing processing");

            // Begin processing a unit of work

            // In this case, just sleep. In real world, processing code goes here:
            Thread.Sleep(6000);  // 6 sec
        }
    }
}
Project Shared\InterprocessCommunicator.vb:
// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Diagnostics;
using System.IO;
using System.IO.MemoryMappedFiles;

namespace Shared
{
    public class InterprocessCommunicator
    {
        private const int MessageByteSize = 4;  // Number of bytes needed to store an int32
        private const int ShutdownMessage = -1;

        private MemoryMappedFile _memoryMappedFile;
        private readonly string _memoryMappedFileName;

        public EventHandler ProcessExited;

        public InterprocessCommunicator(string memoryMappedFileName)
        {
            _memoryMappedFileName = memoryMappedFileName;
        }

        #region Public Methods

        public bool LocateClient()
        {
            try
            {
                _memoryMappedFile = MemoryMappedFile.OpenExisting(_memoryMappedFileName);
            }
            catch (FileNotFoundException)  // Exception-driven logic is never ideal, but no method exists to check for the file first
            {
                return false;  // Client not found
            }

            // Read the process ID from the memory-mapped file:
            var messageReceived = GetMessage();

            // Check if the latest message in the file is a shutdown message
            // sent from a previous instance of this application
            // (which means that the client app is still running but no longer listening-- likely it's shutting down)
            if (messageReceived == ShutdownMessage)
            {
                return false;  // Client not found
            }

            var processId = messageReceived;

            // Get the client process by its ID:
            var process = Process.GetProcessById(processId);
            process.EnableRaisingEvents = true;
            process.Exited += ProcessExited;

            return true;  // Client found
        }

        public bool CheckForShutdownMessage()
        {
            var message = GetMessage();
            if (message == ShutdownMessage)
            {
                Console.WriteLine("Received shutdown message");
                return true;
            }

            return false;
        }

        public void BroadcastProcessId()
        {
            var processId = Process.GetCurrentProcess().Id;
            BroadcastMessage(processId);
        }

        public void BroadcastShutdownMessage()
        {
            BroadcastMessage(ShutdownMessage);
        }

        #endregion

        #region Private Methods

        private void BroadcastMessage(int message)
        {
            _memoryMappedFile = MemoryMappedFile.CreateOrOpen(_memoryMappedFileName, MessageByteSize);

            using (var accessor = _memoryMappedFile.CreateViewAccessor(0, MessageByteSize))
            {
                accessor.Write(0, message);
            }
        }

        private int GetMessage()
        {
            int messageReceived;

            using (var stream = _memoryMappedFile.CreateViewStream())
            {
                var reader = new BinaryReader(stream);
                messageReceived = reader.ReadInt32();
            }

            Console.WriteLine(string.Format("Broadcast '{0}' received", messageReceived));

            return messageReceived;
        }

        #endregion
    }
}
Previous articles:
Reference:

Tool of the Week: Autocorrect Macros with AutoHotkey

Although I'd much rather be coding all day, a good part of my job involves writing e-mail and creating documentation.  And since both can tend to be boring and repetitive, I saw those activities as new avenues for coding.

I found a great (free!) tool called AutoHotKey, a macro language for Windows that allows you to add code for anything and everything you see on the screen.  It's really quite deep, providing for certain actions based on what window is currently selected.  Back in Windows XP and Vista days, I had a macro written that closed the desired application in the taskbar with a middle click of the mouse.  I haven't revisited the script since Windows 7 hit the scene, but I'll bet there's a way to do it.

CloseWindowOnMiddleClick.ahk:

#SingleInstance force

MButton::
MouseGetPos, , , id, control
WinGetClass class, ahk_id %id%

if (control = "ToolbarWindow322" || control = "ToolbarWindow324") {
    Send {RButton}{Esc}{Esc}
    WinGetActiveTitle currentWindow

    if (currentWindow != "") {
        WinClose %currentWindow%
    }

    else {
        Send {MButton}
    }
}

else {
    Send {MButton}
}

return
What I do use AutoHotkey for on a daily basis is a global auto-correct.  Rather than leveraging Microsoft Word's autocorrect feature, I'll add to my existing script whenever I have a new abbreviation that I want spelled out or a new typo that I'll inevitably make so it can be applied across any application.  It's also useful for repetitive stuff: if I type "ssf", it'll replace it with:
SELECT *
FROM 

WHERE
... and it will automatically move the cursor above the "WHERE" clause so I can immediately type the table name in the SQL query.  Here's a sample of my autocorrect macro:
Autocorrect.ahk:
::framwork::framework
::fyi::FYI
::gui::GUI
::ktnx::ok, thanks
::ktny::ok, thank you
::lan::LAN
::sql::SQL
::mgmt::management
::mtg::meeting
::np::no problem
::pls::please
::powerpoint::PowerPoint
::prodn::production
::req::requirement
::reqs::requirements
::sharepoint::SharePoint
::ssf::SELECT *{enter}FROM {enter}WHERE {up}
::ssn::SSN
::ssns::SSNs
::stirng::string
::ty::Thank you
::vpn::VPN
::cache'::Caché
I know I've barely scratched the surface of AutoHotKey.  It's a full-blown programming language and I've just documented it like it's just a simple toy.  But even though I don't have a full grasp of its power, I'm still able to get it to perform simple feats that make redundant parts of my life just a little bit more automated and a little less repetitive.

Interprocess Communication With Memory-Mapped Files, Part 2

In the previous post, I provided a glimpse into how to use a memory-mapped file to establish a primitive interprocess communication system, responsible for passing along the process ID from one process, and a "shutdown gracefully" message from another.

To recap, we have two separate applications:

  • ConsoleAppListener
    Responsible for performing work and shutting down gracefully when it receives a “shutdown” message, after it has finished processing a full unit of work.  Multiple instances can exist, but each has a different “unique name” and a separate ConsoleAppController responsible for starting and monitoring each instance.
  • ConsoleAppController
    Responsible for starting ConsoleAppListener, ensuring it stays running, and sending a “shutdown” message instructing the ConsoleAppListener to shutdown gracefully when it’s finished processing.  Multiple instances can exist, but each is responsible for monitoring a ConsoleAppListener with a different “unique name”.
It can be difficult to explain in words what code can sometimes help clear up, so below I am posting the Program.cs files for each of the two console applications.  Note that the path to the .exe of the Listener app is hard-coded as a constant in the Controller app.
ConsoleAppListener's Program.cs:

 

// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Diagnostics;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading;

namespace ConsoleAppListener
{
    /// <summary>
    /// Responsible for performing a unit of work ("processing") at a time,
    /// checking for a message to shutdown between processing.
    /// </summary>
    class Program
    {
        private const int FileSize = 4;  // Maximum number of bytes needed to hold an int32
        private const int CloseMessage = -1;

        private static string _instanceName;
        private static MemoryMappedFile _memoryMappedFile;

        static void Main(string[] args)
        {
            // Get the unique name of this application from the first commandline argument:
            _instanceName = args.Length > 0 ? args[0] : string.Empty;

            if (string.IsNullOrEmpty(_instanceName))
            {
                Console.WriteLine("Error: Expected a unique name for the application from the command line.");
                Console.Read();
                return;
            }

            _memoryMappedFile = MemoryMappedFile.CreateOrOpen(_instanceName, FileSize);

            using (var accessor = _memoryMappedFile.CreateViewAccessor(0, FileSize))
            {
                var processId = Process.GetCurrentProcess().Id;
                accessor.Write(0, processId);
            }

            while (!ShouldClose())
            {
                Console.WriteLine("Close message not received, beginning to process");

                // Perform a unit of work:
                PerformProcessing();
            }

            Console.WriteLine("Close message received. Hit Enter to close");
            Console.Read();
        }

        private static bool ShouldClose()
        {
            using (var stream = _memoryMappedFile.CreateViewStream())
            {
                var reader = new BinaryReader(stream);
                var message = reader.ReadInt32();
                if (message == CloseMessage)
                {
                    Console.WriteLine("Received shutdown message");
                    return true;
                }
            }

            return false;
        }

        static void PerformProcessing()
        {
            Console.WriteLine("Performing processing");

            // Begin processing a unit of work

            // In this case, just sleep. In real world, processing code goes here:
            Thread.Sleep(6000);  // 6 sec
        }
    }
}
ConsoleAppController's Program.cs:
// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.Diagnostics;
using System.IO;
using System.IO.MemoryMappedFiles;

namespace ConsoleAppController
{
    /// <summary>
    /// Responsible for launching a ConsoleAppListener process with a specific instance name and monitor it,
    /// if one isn't already running. If a ConsoleAppListener is already running, it will begin monitoring.
    /// If the ConsoleAppListener shuts down, this will restart it.
    /// If the user presses any key, the ConsoleAppListener is instructed to shut down gracefully.
    /// </summary>
    class Program
    {
        private const int MessageByteSize = 4;  // Number of bytes needed to store an int32
        private const int CloseMessage = -1;
        private const string ClientAppInstanceName = "SampleApp";
        private const string ClientProcessFileName = @"C:\Code\Personal\InterprocessCommunication\ConsoleAppListener\bin\Debug\ConsoleAppListener.exe";

        private static bool _isClientProcessRunning;
        private static bool _isShuttingDown;

        static void Main(string[] args)
        {
            // Determine whether the client process is already running:
            _isClientProcessRunning = LocateClient(ClientAppInstanceName);
            if (_isClientProcessRunning)
            {
                Console.WriteLine("Process already running");
            }
            else
            {
                // Launch the process:
                LaunchProcess();
                Console.WriteLine("Process launched");
            }

            Console.WriteLine("Hit any key to send shutdown message (at any time)");
            Console.ReadKey();

            WantProcessToShutDown(ClientAppInstanceName);

            _isShuttingDown = true;
            Console.WriteLine("Hit Enter to close");
            Console.ReadLine();
        }

        private static bool LocateClient(string clientAppUniqueName)
        {
            MemoryMappedFile memoryMappedFile;

            try
            {
                memoryMappedFile = MemoryMappedFile.OpenExisting(clientAppUniqueName);
            }
            catch (FileNotFoundException)  // Exception-driven logic is never ideal, but no method exists to check for the file first
            {
                return false;  // Client not found
            }

            int messageReceived;

            // Read the process ID from the memory-mapped file:
            using (memoryMappedFile)
            {
                using (var stream = memoryMappedFile.CreateViewStream())
                {
                    var reader = new BinaryReader(stream);
                    messageReceived = reader.ReadInt32();
                    Console.WriteLine(string.Format("Broadcast '{0}' received", messageReceived));
                }
            }

            // Check if the latest message in the file is a shutdown message
            // sent from a previous instance of this application
            // (which means that the client app is still running but no longer listening-- likely it's shutting down)
            if (messageReceived == CloseMessage)
            {
                return false;
            }

            var processId = messageReceived;

            // Get the client process by its ID:
            var process = Process.GetProcessById(processId);
            process.EnableRaisingEvents = true;
            process.Exited += ProcessExited;

            return true;
        }

        private static void LaunchProcess()
        {
            var process = new Process();

            // Create process to launch the desired application:
            var processProperties = new ProcessStartInfo
                                        {
                                            UseShellExecute = true,
                                            WorkingDirectory = Directory.GetParent(ClientProcessFileName).FullName,
                                            FileName = ClientProcessFileName,
                                            Arguments = ClientAppInstanceName,  // Pass in the application's unique name
                                            RedirectStandardOutput = false
                                        };

            Console.WriteLine(String.Format("Launching executable: {0} {1} ", processProperties.FileName,
                                      processProperties.Arguments));

            process.StartInfo = processProperties;
            process.EnableRaisingEvents = true;
            process.Exited += ProcessExited;
            process.Start();
            _isClientProcessRunning = true;
        }

        private static void ProcessExited(object sender, EventArgs e)
        {
            Console.WriteLine("Process exited");
            _isClientProcessRunning = false;

            // Start up the process again:
            if (!_isShuttingDown)
            {
                LaunchProcess();
            }
        }

        private static void WantProcessToShutDown(string destinationAppName)
        {
            if (!_isClientProcessRunning)
            {
                return;
            }

            var memoryMappedFile = MemoryMappedFile.OpenExisting(destinationAppName);

            using (var accessor = memoryMappedFile.CreateViewAccessor(0, MessageByteSize))
            {
                accessor.Write(0, CloseMessage);
            }

            Console.WriteLine("Sent message to shut down");
        }
    }
}

Ideally, this has provided you with the framework to create a basic method for allowing two processes to talk; the controller can notify the listener when it's time to shut down gracefully, and the listener can broadcast its process ID in case the controller shut down unexpectedly.

Note: Part 3 was written to refactor the above code in a more efficient and encapsulated format.  I'd highly recommend checking that out too.

Part 1
Part 3

Interprocess Communication With Memory-Mapped Files, Part 1

Memory-mapped files are great concept that have been buried in various versions of Windows for years.  Finally they've been exposed and incorporated into .NET 4.0 and are available in Visual Studio 2010.

A memory-mapped file is essentially just a file, given a unique name-- no extension necessary-- that exists only in memory.  It can be used to cache a large file into memory for faster access and manipulation.  In addition, since they're accessible from the system level, these files can be used to allow multiple processes to communicate (called "interprocess communication").  It's this method of communication that I'd like to try to implement here.

Suppose we have two separate processes, one to perform work, and the other that's simply responsible for starting the first-- like a Windows Service.  In this situation, we're assuming that the Windows Service can't simply perform the work in a child thread, but relies on that other process to do it.

I've created two C# projects, with one intended perform "processing" and the other to launch and communicate with the first:

  • ConsoleAppListener
    Responsible for performing work and shutting down gracefully when it receives a "shutdown" message, after it has finished processing a full unit of work.  Multiple instances can exist, but each has a different "unique name" and a separate ConsoleAppController responsible for starting and monitoring each instance.
  • ConsoleAppController
    Responsible for starting ConsoleAppListener, ensuring it stays running, and sending a "shutdown" message instructing the ConsoleAppListener to shutdown gracefully when it's finished processing.  Multiple instances can exist, but each is responsible for monitoring a ConsoleAppListener with a different "unique name".
Since a memory-mapped file has a unique name and persists only while a process is using it, it is a strong candidate for meeting these requirements.  The first process to start, expected to be the ConsoleAppController, is responsible for creating the memory-mapped file.  The second process, the ConsoleAppListener, will look for a memory-mapped file with the same unique name it was provided in its command-line arguments.
Here's a rough order of execution, although many of these things can happen in parallel:
  1. ConsoleAppController starts, checks if a memory-mapped file exists with the name "SampleApp"
  2. ConsoleAppController reads the memory-mapped file, checks if a process ID has already been recorded. If so, this means ConsoleAppListener is already running and will now be monitored.  Otherwise launches a new ConsoleAppListener process with the "SampleApp" passed as a command-line argument
  3. ConsoleAppListener starts, creates or opens memory-mapped file with the name "SampleApp"
  4. ConsoleAppListener saves its process ID to the memory-mapped file
  5. ConsoleAppListener performs processing, checking periodically for the shutdown message, "-1"
  6. ConsoleAppController monitors, restarts ConsoleAppListener if it shuts down on its own (e.g. user closes the window)
  7. ConsoleAppController saves a shutdown message, "-1", to the memory-mapped file, instructing ConsoleAppListener to shutdown at an appropriate time (when it's not performing processing)
So in this scenario, the mem0ry-mapped file only needs to be large enough to store an int32, representing either the ConsoleAppListener's process ID or a shutdown message of "-1".  The direction of either message is implied, as the listener only cares about receiving a "-1" and the controller is only interested in a process ID (which is greater than -1).  For that reason, I consider this mechanism more of a passive, broadcast-based communication system, rather than an active, full-duplex sort of client-server arrangement.
Here's some of the code used by the ConsoleAppListener, responsible for listening for a shutdown message:
private static bool ShouldClose()
        {
            using (var stream = _memoryMappedFile.CreateViewStream())
            {
                var reader = new BinaryReader(stream);
                var message = reader.ReadInt32();
                if (message == CloseMessage)
                {
                    Console.WriteLine("Received shutdown message");
                    return true;
                }
            }

            return false;
        }
Here's part of ConsoleAppController, responsible for locating the memory-mapped file ("destinationAppName" is the name of the memory-mapped file) and sending a shutdown message to the ConsoleAppListener if prompted by the user:
        private static void WantProcessToShutDown(string destinationAppName)
        {
            if (!_isClientProcessRunning)
            {
                return;
            }

            var memoryMappedFile = MemoryMappedFile.OpenExisting(destinationAppName);

            using (var accessor = memoryMappedFile.CreateViewAccessor(0, MessageByteSize))
            {
                accessor.Write(0, CloseMessage);
            }

            Console.WriteLine("Sent message to shut down");
        }
I hope this preview gives at least some insight into the use of memory-mapped files for primitive interprocess communication.  In tomorrow's post I'll be providing all of the sample code.

Setting the Netduino's DateTime Automatically

Whenever the Netduino boots up or is restarted, you'll find that the date and time reverts to the default values.  Since the release of the Netduino Plus, ethernet access has been built in and provides a welcome solution to this issue.

The Network Time Protocol (NTP) provides an easy way to sync a device (such as your Windows computer) with a network time server.  By invoking an NTP server at start-up, the Netduino will automatically set its DateTime.

The following code was provided on a blog by Michael Schwarz and slightly modified to accept an additional (time zone) parameter:

using System;
using System.Net;
using System.Net.Sockets;

public static class Ntp
{
    public static bool UpdateTimeFromNtpServer(string server, int timeZoneOffset)
    {
        try
        {
            var currentTime = GetNtpTime(server, timeZoneOffset);
            Microsoft.SPOT.Hardware.Utility.SetLocalTime(currentTime);

            return true;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// Get DateTime from NTP Server
    /// Based on:
    /// http://weblogs.asp.net/mschwarz/archive/2008/03/09/wrong-datetime-on-net-micro-framework-devices.aspx
    /// </summary>
    /// <param name="timeServer">Time Server (NTP) address</param>
    /// <param name="timeZoneOffset">Difference in hours from UTC</param>
    /// <returns>Local NTP Time</returns>
    private static DateTime GetNtpTime(String timeServer, int timeZoneOffset)
    {
        // Find endpoint for TimeServer
        var ep = new IPEndPoint(Dns.GetHostEntry(timeServer).AddressList[0], 123);

        // Make send/receive buffer
        var ntpData = new byte[48];

        // Connect to TimeServer
        using (var s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
        {
            // Set 10s send/receive timeout and connect
            s.SendTimeout = s.ReceiveTimeout = 10000; // 10,000 ms
            s.Connect(ep);

            // Set protocol version
            ntpData[0] = 0x1B;

            // Send Request
            s.Send(ntpData);

            // Receive Time
            s.Receive(ntpData);

            // Close the socket
            s.Close();
        }

        const byte offsetTransmitTime = 40;

        ulong intpart = 0;
        ulong fractpart = 0;

        for (var i = 0; i <= 3; i++)
            intpart = (intpart << 8) | ntpData[offsetTransmitTime + i];

        for (var i = 4; i <= 7; i++)
            fractpart = (fractpart << 8) | ntpData[offsetTransmitTime + i];

        ulong milliseconds = (intpart * 1000 + (fractpart * 1000) / 0x100000000L);

        var timeSpan = TimeSpan.FromTicks((long)milliseconds * TimeSpan.TicksPerMillisecond);
        var dateTime = new DateTime(1900, 1, 1);
        dateTime += timeSpan;

        var offsetAmount = new TimeSpan(timeZoneOffset, 0, 0);
        var networkDateTime = (dateTime + offsetAmount);

        return networkDateTime;
    }
}

Here's a short list of some NTP servers:

  • pool.ntp.org (actually it's a collection of servers behind a single address)
  • time.nist.gov
  • time-a.nist.gov
  • time-b.nist.gov
Pass one of these server names as a string and call during your project's Main() method:
private static bool SetTime()
{
    var result = Ntp.UpdateTimeFromNtpServer("time.nist.gov", -4);  // Eastern Daylight Time
    Debug.Print(result ? "Time successfully updated" : "Time not updated");

    return result;
}
It's unfortunate that the Netduino doesn't support Microsoft.SPOT.ExtendedTimeZone.SetTimeZone() to allow a time zone to be specified (thus eliminating the need for that extra "timeZoneOffset" parameter I added to two of the methods) or even the Microsoft.SPOT.Time.TimeService.UpdateNow() method, which would make all of the code above obsolete. However, it's understandable some libraries needed to be stripped due to memory size limitations. I'm still a huge fan of the Netduino; it still offers a lot of functionality on a very small and cheap device.

Additional References:

Blast From the Past: GW-BASIC

A few weeks ago, I decided to clean up my bookshelves and finally toss a bunch of antiquated software development books.  Technologies like HTML 3.2, Visual Basic 6, and Visual J++ didn't survive this latest purge.  But there's one book that I just can't seem to toss, no matter how much relevance it's lost.  It's the GW-BASIC User's Guide and Technical Reference, which was included with my very first computer, a CompuAdd 8086.

GW-BASIC was a port of the BASIC (Beginner's All-Purpose Symbolic Instruction Code) language, and was one of the many BASIC products borne from the assembly line of early Microsoft.  It was packaged with earlier versions of MS-DOS, the operating system of choice for IBM-compatible PCs.

To give some insight into what intrigued me last, my copy of this book still has Post-Its on the keywords Get, Paint, and Window-- all three dealing exclusively with primitive GUI elements on the screen.  I never got anywhere with those, I'm sure of it.  But what I find funny is that the first half of the book, the user's guide, is completely devoid of marks of any kind; I doubt I ever actually read about how to actually use the development tool.  I learned by doing and didn't let myself get caught up on fundamentals like relational, logical, or functional, or string operators.  In fact, not until today did I even know that GW-BASIC even allowed low-level assembly calls!

GW-BASIC existing during a time in my life where I just didn't understand why things worked the way they did; I simply copied from a plethora of magazine articles and even a book or two (David Ahl's Basic Code Adventures and Creating Adventure Games on Your Computer by Tim Hartnell).  It was all trial and error, and it was great.

Line-numbering is obligatory.  Without line numbers, you're indicating to the IDE that you want your expression to be evaluated immediately.  Common practice was to number lines in increments of 10, with the idea that if you needed to insert another line between 10 and 20, you could choose line 12 or maybe 15 to squeeze in that additional piece of code.  A simple RENUM command will renumber the lines, including lines referenced by GOTOs.

Type-checking is kept to a minimum and is quite forgiving.  Variable types, although not required, were denoted by the following postfixes:
$ String
% Integer
! Single-precision
# Double-precision

GW-BASIC had limited support for subroutines.  Subroutines (via the GOSUB statement) were perceived as GOTOs that included a RETURN statement to bring the code execution back to where the calling GOSUB left off.

GW-BASIC's successor, QBASIC, introduced more elegant sub and function calls as well as the concept of line labels, eliminating the need to identify each line with an incremented number.  Plus it allowed mouse input, something that's easily taken for granted today.  QBASIC would set the stage for Visual Basic, which finally brought BASIC into the new graphics-rich Windows operating system.

Additional links:
http://www.atariarchives.org/bca/index.php
http://www.atariarchives.org/adventure/
http://www.gw-basic.com

Tool of the Week: Sending Faxes With HelloFax

It may not be that often that a developer needs to use a fax machine.  For some of us, having one nearby is one of the perks of working in an office building.  For others, taking a trip to the local copy shop can take a good deal of your time, cash out of your wallet, and gas out of your car.   I don't like using up more time, money, or even paper than I need.

So when I recently had to send a constantly-revised contract back and forth, I finally took a fresh look at the web-based faxing services.  It's not necessarily a new concept, scanning a document, uploading it, typing in a fax number and hitting send, but I was a bit embarrassed that I hadn't looked at these services  before spending about $20 (no joke) at FedEx while coping with two paper jams and some frustrated looks at the folks waiting to use the fax too.

The first service I tried, HelloFax, was the one I've stayed with.  I learned about it on Lifehacker and I liked the fax fact that the first few pages I sent were free.  I could upload different types of documents (PDF was my doc of choice) and they could even whip up a free cover page on the fly.  I hated creating cover pages; the Word template I created just never seemed to format right.

HelloFax didn't betray the fact I'm cheap and that I didn't use a real fax machine when it came time for me to send out some documents.  Only if you choose to use a cover page generated by the service, it'll add the phrase "Powered by HelloFax" on the page.  But otherwise, no ads.

Its interface is clean and allows you to edit your document by adding text, checkboxes, and even signatures (uploaded, drawn with your mouse, or taken as a picture from your phone and e-mailed to a special e-mail address).

Sending faxes is queue-based; when you click "send", you can walk away and the fax is sent in short order.  You can even get an e-mail (with an attached copy of what was sent) notifying you when the send is successful.

The service is free if all you want to do is send 5 pages-- which can be spread over one or more faxes)-- then it's 99 cents to send a fax up to 10 pages (then 20 cents per page after that).  If you visit their site through a referral link like this one, they'll give you 5 more free pages on sign-up.

There are pay plans, which I have not tried.  The cheapest plan, at $5 per month, offers 50 pages a month and you're given your own local phone number to receive faxes as well.  The higher-tiered plans offer more and more pages and still seem like a good deal if your life involves being chained to a fax machine.

How to Catch Multiple Exceptions in C#

Here's a technique for catching more than one exception in a try / catch block.  Typically it's best to only catch the exceptions that your code can handle, so catching the general System.Exception class is discouraged.  But in this case, we're catching the general Exception class only to determine what type of exception it is.  For any exceptions that aren't handled in the if / else if blocks, we'll re-throw the exception for the calling method to handle.

catch (Exception exception)
{
	if (exception is FileNotFoundException)
	{
		Console.WriteLine("Error: File not found");
	}
	else if (exception is ArgumentException || exception is ArgumentNullException || exception is DirectoryNotFoundException)
	{
		Console.WriteLine("Error: Path is invalid or does not exist");
	}
	else
	{
		throw;
	}
}

The entire console application (Program.cs):

// Code from www.jaypm.com
// Feel free to use, but please give credit where it's due.

using System;
using System.IO;

namespace MultipleExceptionHandler
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                using (var fileReader = new StreamReader("file.txt"))
                {
                    while (fileReader.Peek() > 0)
                    {
                        Console.WriteLine(fileReader.ReadLine());
                    }
                }
            }
            catch (Exception exception)
            {
                // Check if it's one of three different exceptions:
                if (exception is ArgumentException || exception is ArgumentNullException || exception is DirectoryNotFoundException)
                {
                    Console.WriteLine("Error: Path is invalid or does not exist");
                }
                // Otherwise check if it's another exception:
                else if (exception is FileNotFoundException)
                {
                    // NOTE: This was only an example to demonstrate handling multiple exceptions.
                    //        It's more efficient to use File.Exists(fileName) rather than using an exception
                    //        to drive your logic.
                    Console.WriteLine("Error: File not found");
                }
                // Since we caught the generic System.Exception, this "else" case will
                // throw back up anything that wasn't explicitly caught:
                else
                {
                    throw;
                }
            }
            Console.ReadLine();
        }
    }
}