The .NET Micro Framework comes with sophisticated and - what is more important - extensible emulator architecture. Unfortunately the projects for creating emulators in Visual Studio force us to use somewhat obsolete technology - Windows Forms. Although Steve just introduced his series about creating emulators for Windows Presentation Foundation, I have decided to publish my already written article in case anybody of you simply can't wait any longer. :-)
Emulators are plain .NET applications like any other, which means, that it shouldn't be any problem to create an emulator eg. in a form of Windows service, or say inside Windows Workflow Foundation. :-)
There is a new project type coming with .NET Micro Framework SDK, called Device Emulator, which is intended specially for this task. It brings three main features, which we will have to implement ourselves in when creating our independent emulators. The first one is registration of the emulator into the Visual Studio. This assures that the emulator is showed in the emulators list in the properties of .NET Micro Framework application, as soon as you make a first successfull build. The next one is generation of empty Emulator.config file, and its automatic loading during runtime. Last, but not least, it generates the emulator template itself, a class derived from Microsoft.SPOT.Emulator.Emulator.
So where is the problem? Why can't we just use this project and create for example a Window Presentation Foundation window instead of Windows Forms form? Well the problem is, that the WPF application - like many others - is a special type of project. Until your emulator becomes of that special type, you will be able to add only standard items into the project (and I suspect the User Control (WPF) is offered by mistake):
The first solution is to create the project you need, and somehow squeeze the emulator in. That way we will lose the advantages mentioned above, Let's try to implement them.
This one is quite easy - it's just a short registry writing:
string keyBase = @"HKEY_CURRENT_USER\Software\Microsoft\.NETMicroFramework\v3.0\Emulators\MyEmulator"; Microsoft.Win32.Registry.SetValue(keyBase, "Name", "My Emulator"); Microsoft.Win32.Registry.SetValue(keyBase, "Path", @"C:\Path\To\MyEmulator.exe"));
However, this solution is not very flexible one. You have to check the current framework's version, and if the team decides to change the registry structure, or adds some additional steps required to successfully register the emulator, you will hardly get informed. On the other side it is probably the only one distributable possibility. The Visual Studio actually uses the RegisterEmulator class in Microsoft.SPOT.Tasks.dll assembly, which you can find in the Tools SDK folder. If you want to depend on the .NET Micro Framework SDK installation (which is not that unreasonable assumption), you can use it too. In that case, this line will do:
new Microsoft.SPOT.Tasks.RegisterEmulator { SubkeyName = "MyEmulator", Name = "My Emulator", Path = @"C:\Path\To\MyEmulator.exe" }.Execute();
The standard emulator project contains an empty Emulator.config file, which you can use to change the emulator's configuration without rebuilding it. This file is during building copied to the output folder, with the same name as your executable and .emulatorconfig extension. This luxury can be compensated using these steps:
What remains now is to add a referenct to the Mirosoft.SPOT.Emulator assembly and start the emulator class by calling MyEmulator.Start() during runtime, which is allowed to happen in another thread, too. In the installed emulator project template, the Main method is used to create and run the emulator, and everything else needed to run your application takes place in the emulator's Initializeomponent() method:
Of course it is no problem to make it the other way, starting the emulator instance from your application code base.
The second option is to use the standard emulator template as is, and smuggle the desired technology inside. The Visual Studio distinguishes between different project types (eg. Windows Forms Application × WPF Application × ASP.NET Web Application × Word 2007 Add-in etc.) and uses this information to adjust the project behavior, including the list of available project items (Windows Form × WPF Window × Web Form × Word Document etc.). Each project type has assigned its own GUID, which is stored in the .csproj file. As an example, if you are creating a WPF Application and open the project file say in notepad, you will see <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <AssemblyName>WpfApplication1</AssemblyName> <OutputType>WinExe</OutputType> <RootNamespace>WpfApplication1</RootNamespace> <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProductVersion>9.0.30729</ProductVersion> <ProjectGuid>{34895117-845f-4fef-9ea4-26211b9c3d15} </ProjectGuid> ... </PropertyGroup> ...
The ProjectTypeGuids element determines of what type the project is. {60dc8134-eba5-43b8-bcc9-bb4bc16c2548} means WPF application, {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} stands for C# language. As you have probably already guessed, you need to take these GUIDs and insert them into the project file of your emulator. If it already contains the ProjectTypeGuids element, just use semicolon to separate the GUIDs, if not, feel free to create it - in the first /Project/PropertyGroup element, as shown above. Save, and open the project in Visual Studio again (or just reload). Now when you want to add a new project item, various sweets are waiting for you:
If you have the .NET Micro Framework SDK, have read through the whole article down to here, and you want any of your project types to behave like emulator without the need to implement the functionality yourself as in the first part, I have a nice surprise for you - you can do that. You only have to notice some of the inconspicious part in the emulator's project file:
Insert the marked lines into your project file, and they will gain the functionality of emulator projects immediately. Remember this is only a help during the emulator development for you, which you don't have to use (eg. if you don't like the automatic registration) - this trick even does not work if you don't have the .NET Micro Framework SDK installed. Advanced developers can go further, and see or adjust the mentioned .target files to their liking (eg. switch off the registration stuff only). Though, woe betide you who will end up with wrecked studio asking for help in the community! :-)