elcome to Mobile CoDe.NET, the regular CoDe Magazine column dedicated to the development of mobile business solutions using Microsoft .NET mobility technologies. In the last issue, we explored the various Microsoft technologies for mobile development and the field of mobility in general. If you haven’t checked it out yet, I strongly suggest you dig out the July/August issue from under your two-month supply of empty pizza boxes and start reading.
The combination of the .NET Compact Framework with the Smart Device Extensions (SDE) in Visual Studio .NET 2003 finally brings us into a mature playing field for mobile application development. The .NET Compact Framework is the mobile arm of the .NET platform, which you can use to develop rich-client applications for Windows CE.
You’ll remember I brushed the “Windows vs. Web” topic very rapidly as it applies to mobile development. And while I’m not here to reopen the debate or force you down one path, I’ll nonetheless thread the “Windows” path over the next few pages to enlighten you on how to build rich-client mobile applications for Windows CE using the .NET Compact Framework. I promise I’ll cover the “Web” path and the ASP.NET Mobile Controls in a future issue.
.NET Device Programming
With the release of Visual Studio .NET 2003 in April, .NET developers can now extend the .NET programming model to software development projects targeting smart devices. By smart device, we usually mean a mobile device of some sort with a relatively low encumbrance factor. This could potentially include notebooks and Tablet PCs, but for the sake of this column, I typically limit the term to the various devices running one inception or another of Windows CE.
The fusion of at least three radically different programming models in .NET was in itself an already amazing feat. No longer would programming practices be limited to a programming language. All .NET languages can now benefit from RAD (Rapid Application Development, both a blessing and a curse) using forms and the composition of graphical controls to design a GUI, which was brought to us by the Visual Basic world. All .NET languages can now use the power of subclassing to inherit and extend the functionality of a library of base classes (? la C++ or Java) thus maximizing the functionality of an application while minimizing code and low-level plumbing. All .NET languages can now be used to build Web-based applications by embedding server-side code inside dynamically generated HTML pages, thus fusing forever the paradigms of Web development and OOP.
Traditionally, mobile development would introduce yet another programming model specific to the language, the device, the operating system and the development environment. This meant that?with all the device types, OS generations and vendors out there?mobility developers would have to specialize on a single mobility platform or become jacks-of-all-trades on many of them. With .NET, device programming doesn’t bring a new programming model, it reuses an existing one: the .NET model, which is the merger of all those models outlined above, taking root in the worlds of Visual Basic, C++, J++, ASP, and others.
You may not have to learn an entirely new programming model here, but you nevertheless have to learn how to think about a new platform. This isn’t your cushy little Windows world anymore; you are entering Windows CE territory and your primary vehicle will be the .NET Compact Framework.
What Is the .NET Compact Framework?
Microsoft introduced the .NET Compact Framework to bring the “managed” world of .NET to Windows CE and smart devices. The .NET Compact Framework (.NETcf) is in fact the little cousin of the full-featured .NET Framework which has so radically changed the landscape of Windows and enterprise development over the past 18 months. This analogy actually works pretty well since your little cousin would merely be a smaller “being” very similar to you, not an incomplete version of you with missing parts. The same goes for the .NET Framework and .NETcf: the .NET Compact Framework isn’t missing any vital organs found in the full .NET Framework, most of it is there; it is only smaller and less powerful.
So why is the .NET Compact Framework smaller? Why do we have to compromise? Well, for starters, the full .NET Framework 1.1 is well over 20 MB in size and most Windows CE devices only have a total of 32 or 64 MB of memory, roughly half of which is used for storage and the other half for program memory allocation. Even if the whole thing was put in ROM (which would require to more than double in size), there still wouldn’t be enough RAM or CPU power to run anything. It’d be like running Windows XP and a .NET application on an old Pentium 75 MHz with 32 MB of RAM. The bottom line is very simple: the .NET Framework wasn’t designed for such a resource-constrained environment and smart devices needed their own version of .NET.
This is exactly what we got: a scaled-down version of the .NET Framework designed specifically for smart devices and optimized for this limited environment. So what’s in there you might wonder? The fact .NET was scaled down implies something was either cut or reduced in functionality, this is true, but instead of focusing on what didn’t make the cut, let’s start with what we do get in the .NET Compact Framework 1.0:
- A “compact” CLR (Common Language Runtime) which serves as the execution engine for your managed mobile applications.
- Support for the full Visual Basic .NET and C# languages.
- A library of base classes which is in fact a 25-30% subset of the full base class library from the .NET Framework 1.1.
- A Global Assembly Cache (GAC) that acts as a repository for your shared assemblies and the base class libraries.
- Error string files (one per language).
- Globalization data files (one per language/region package).
- All within a 2.5 MB deployment package.
Throughout this article I’ll expand on most of these characteristics, but for now, let’s answer the following question: How do you build applications to target the .NET Compact Framework? The answer lies in a new feature of Visual Studio .NET 2003: the Smart Device Extensions.
Smart Device Extensions
Contrary to the previous approach for mobile development in the Microsoft world where the Embedded Visual Tools 3.0 required a separate IDE outside of Visual Studio 6.0, the Smart Device Extensions (SDE) are integrated directly in the Visual Studio .NET 2003 IDE. This feature is available to the Professional Edition and above in Visual Studio .NET 2003 and unless you perform a full install, make sure you select the “Smart Device Programmability” under the Visual Basic .NET and Visual C# .NET languages during setup when choosing which options to install.
With this IDE integration comes a lot of power since you get to use existing Visual Studio components and apply them to mobility projects, such as the Solution Explorer, the Toolbox, the Server Explorer, the Class Viewer, all the documentation features, and many more. For example, the integration with the SDE enables IntelliSense to know which classes exist in the full .NET Framework 1.1 and which can be used legally in SDE projects, thus optimizing productivity regardless of the project type. IntelliSense isn’t your only guide in terms of discovering what’s in and what’s out. The MSDN documentation that ships with Visual Studio .NET 2003 also covers the .NET Compact Framework by tagging supported class members throughout the thousands of online pages with the “Supported by the .NET Compact Framework” label. Hit F1 and search for any class in there and look for this label, indicating whether or not you can use that class or member in your SDE projects.
MSDN also allows you to filter its massive content by selecting the Filtered by option in the Contents pane and then choosing the .NET Compact Framework as the filter parameter. While this will narrow down the library considerably, it won’t remove unsupported class members from supported classes. Ultimately, you’ll soon realize that trying it first hand is the best way to go since there are a few class members that still won’t work even if they are marked “Supported by the .NET Compact Framework.”
Getting Started with the Smart Device Extensions
Let’s begin by creating a new SDE application. Make sure you have the latest Visual Studio .NET 2003 installed, Professional Edition or higher, and that you have selected support for mobile development under either Visual Basic .NET or Visual C# .NET during setup. While all the precepts presented here and in future issues apply to both Visual Basic .NET and Visual C# .NET, being the veteran VB guy that I am I’ll stick to the former in all my samples.
Create a new project, select the Smart Device Application template under the Visual Basic .NET branch and name it MobileCoDeSDEApp. Once you accept these options, you are presented with another window and it is… you’ve guessed it… a wizard! More specifically the Smart Device Application Wizard. Don’t gasp or expect too much though, this is merely a popup asking you to choose two options: the targeted platform, and the mobile project type you want to create.
Selecting Windows CE would mean targeting a generic Windows CE .NET 4.1 device, but since these devices are still fairly rare, we’ll opt for Pocket PC support, which is probably what you are most familiar with if you own a Microsoft Pocket PC 2002 device such as an iPaq, a Dell Axim, a Toshiba e740, or some other compatible device. If you do not own a device, you needn’t worry; the SDE features a choice of powerful smart device emulators for you to test with. In fact, choosing a target platform in this window configures your SDE project to use the proper emulator for when you eventually deploy and test your mobile application. Select Pocket PC as the platform for now. Future articles will focus on Windows CE .NET if you’re interested in this next-generation Windows-Powered platform.
The second option you must select in this wizard is the project type. Just like in standard .NET Framework applications, SDE projects can be used to create many types of applications. There are naturally fewer options, especially since all server-side ASP.NET-based applications, including Web Forms and XML Web services projects, do not exist in the world of the .NET Compact Framework.
You can either create your whole project from scratch using the Empty Project template or you can create applications without any graphical user interface (GUI) using the Non-Graphical Application option. This latter option differs depending on the targeted platform. On the Pocket PC, it means the application is invisible and cannot display text or capture user input. This is because the notion of a console doesn’t exist in that variant of the OS. If you target Windows CE.NET (feel free to try selecting it to see the difference), that option is replaced by a Console Application list item to select from. This should then be familiar territory for console application developers on the desktop. Don’t be fooled, because the Console object does exist and work (i.e. no exceptions thrown) in the .NET Compact Framework, even in Pocket PC projects, but its ReadLine, Write and WriteLine members are useless in such a case.
The two options you are most likely to use are the Windows Application and Class Library project types. Provided you stick to the bounds of .NET Compact Framework classes, class libraries work in pretty much the same way as their desktop of server counterparts. These are in-process .NET assemblies (.dll) that run within the same application domain as the calling assembly (.exe), and their usage within a client application architecture follows the same rules you are already familiar with. Let’s pick the Windows Application project type, which is a standard .NET assembly compiled as an IL (Intermediate Language) portable executable (.exe), since we want to design a Pocket PC application that sports a form-based GUI.
Once you accept these settings, Visual Studio .NET and the SDE proceed to creating a basic Pocket PC application project that is ready for device deployment. The SDE features a Windows Forms designer very similar to the one used in standard Windows Forms projects. You’ll notice the form is automatically sized to the proper Pocket PC screen dimensions and even though you can resize the form, you should leave it as it is to ensure that your application interface covers the whole display area.
Before adding controls and code to our new mobile application, I want to make sure we cover the basics of the SDE and .NET Compact Framework features. Jumping in blindly can be fun at times, but understanding the development mechanisms and the underlying architecture of this mobile framework is too important to ignore. Don’t forget: RAD stands for Rapid, not Reckless Application Development.
Working with the Emulator
|Figure 1: The Smart Device Extensions in Visual Studio .NET 2003 feature powerful emulators that allow you to test .NET Compact Framework applications for the Pocket PC 2002 or Windows CE .NET 4.1. These “virtual devices” can be configured to emulate a wide range of configurations depending on the needs of your specific projects.|
Running and testing a .NET Compact Framework application is a bit different than it is for standard Windows projects. In fact, it’s a bit like Web development: just like ASP.NET applications (i.e. Web Forms) need to be tested in their run-time environment?the Web browser?.NET Compact Framework applications need to be tested in their own run-time environment: a “smart” Windows Powered device, or an emulated version of one. I already mentioned the emulators included with the SDE. These are, in fact, a single emulator engine running Virtual PC technology from Connectix packaged with multiple OS images. Each image contains a full instance of the mobile OS and can run in Virtual PC emulation on top of an x86 processor. There are two default images you can use, one for each of the two platforms you can target with the SDE: Pocket PC 2002 and Windows CE.NET 4.1. With newer versions of mobile OS specs based on Windows CE.NET 4.2 on the way?such as the new Windows Mobile 2003 (see the Mobility World News sidebar) and others?you can expect Microsoft to provide additional SDE support and emulator images in Visual Studio .NET updates in the coming year. And with Microsoft’s acquisition of the Connectix Virtual PC technology earlier this year, you can also expect to see it creep into many other products in the near future.
To see the emulator in action, simply use the Connect to Device option from the Device toolbar. It is also available under the Tools menu in the Visual Studio .NET 2003 IDE. The SDE then launches the emulator and loads the default OS image for Pocket PC 2002 (see Figure 1). Feel free to click around using your mouse; you’ll soon realize all the basic Pocket PC 2002 features are there, from Pocket Word to Solitaire. It’s a good idea to leave the emulator loaded and connected while building and testing SDE applications. This way you’ll save yourself the time it takes to launch the emulator every time you run your application. But for now, close the emulator since we’ll look at configuration options.
You’ll notice there are two options presented to you in the Shut Down dialog window that appears when you close the emulator: you can select Save Emulator state to preserve all the settings you have configured, applications you loaded and files you transferred (just like a real device which maintains a persisted state), or you can select Turn off emulator, in which case all your changes made in terms of device configuration and files copied are lost and the emulator reverts back to the default “vanilla” package.
Since not all Pocket PCs are identical, you might want to configure this device. Not all Pocket PCs feature the same amount of memory or support the same color depth. Fortunately, you can tweak a few options to make the emulator’s behavior closer to the actual device you’ll be deploying to in production. Select the Device Options button on the Device toolbar to access these configuration options (see Figure 2). You are presented with three tab pages of options. The first allows you to change the screen size and color depth. Since all Pocket PC 2000/2002 devices support a fixed 240×320 screen resolution, I advice against changing that. These settings are typically reserved for generic Windows CE projects where the screen resolution is variable from device to device (e.g. 240×320, 320×240, 640×240, 640×480, 800×600, etc.)
|.NET Compact Framework: The Architecture|
The .NET Framework is what could be called a high-level platform in that it shields developers from the intricacies of the Win32 API and the low-level plumbing that would normally be required. The .NET Compact Framework works in the same way, isolating you from the nitty-gritty details of Windows CE development. It nonetheless remains important for developers to understand how that platform works and what kind of architecture lies underneath. Note that for the sake of discussion here, I assume you are already somewhat familiar with the basic architectural workings of the .NET Framework.
The basic architecture of the .NET Compact Framework starts with the Execution Engine (EE), which is the core component that manages everything else in .NET. This is where you’ll find the Common Language Runtime (CLR) designed for the .NET Compact Framework. This CLR works just like the CLR in the .NET Framework by consuming IL assemblies to produce native code for the target CPU. Since the Execution Engine is built in native code, there is one set of EE files for every CPU and Windows CE OS supported. The CLR is contained in the MSCOREE.dll and MSCOREE1_0.dll files, which also contains the Platform Adaptation Layer (PAL). This layer is akin to the Hardware Adaptation Layer (HAL) in Windows NT-based operating systems (Windows NT 4.0, 2000, XP, 2003) in that is serves as a “translation” tier between generic code and a hardware specific CPU. This PAL is what enables any .NET Compact Framework assembly to run on any compatible Windows CE device using any CPU, whereas classic Embedded Visual C++ applications would require a separate recompile for each OS and CPU. Other native code files outside of the EE include NETCFAGL.dll for the GWES (Graphics, Windowing, and Events Subsystem) interface, which is the graphical user interface between the user, application, and the operation system, and CGACUTIL.exe for the Global Assembly Cache (GAC) manager.
Indeed, there is a GAC in the .NET Compact Framework where you can deploy you own assemblies for shared reuse. It comes preloaded with a subset of the .NET base class libraries, which are CPU- and operating system-independent managed DLLs you can call from your applications through references to reduce the overall amount of code required. These class libraries follow the same hierarchical structure of namespaces as the ones found in the .NET Framework 1.0 and 1.1. I’ll come back to .NETcf namespaces very soon.
I mentioned earlier that only Visual Basic .NET and Visual C# .NET were supported in the .NET Compact Framework. This is not entirely true. Since the CLR only runs IL code, this means any .NET language could potentially be used to create .NET Compact Framework assemblies. The limitation to these two languages actually rests on the SDE which only initially supports VB .NET and C# from Microsoft. Should another company decide to port their .NET language to .NETcf and create an SDE-style compiler that understands the limitations, the compact CLR would accommodate it just as well. I have not seen any official announcement yet as far as .NETcf third-party languages are concerned.
One interesting difference in the architecture lies in the way error messages are handled. Typically, when an error is raised, an error message accompanies it and the developer can choose to display it or display their own message to the end user. In the .NETcf, Microsoft extracted all the error messages for memory considerations and put them in separate error string files (SYSTEM.SR.dll). There is one such file per supported language and you can choose whether to deploy an error string file or not along with your mobile application.
.NET Framework: Compact/Desktop Commonalities
And while it may be compact, the “mobile” CLR is just as complete. The Garbage Collector (GC) eliminates the need for reference counting (? la COM), allocates and deallocates memory, and prevents memory leaks. The “Blue Screen of Death” may not exist in Windows CE, but memory corruptions can still occur and the .NETcf GC safeguards what happens in those tiny application domains. Just-in-Time (JIT) compilation is also inherited from the desktop cousin. .NETcf strictly runs IL code and nothing else, and with many more CPUs on mobile devices than on the desktop, this design feature brings many more benefits, such as portability of assemblies, facilitated deployment, and more.
Should something go haywire in your code, error handling in .NETcf also relies on structured exception handling; using the same constructs you have become familiar with in .NET. And of course, there’s the Common Type System (CTS) which brings unity across data types and languages. You’ll be pleased to hear that all the basic types (e.g. Boolean, integer, long, string, decimal, etc.) made it to the .NETcf, ensuring compatibility between desktop, server, and mobile code. As for complex types and other classes, it depends on their respective namespaces.
The object model is also the same, giving you full access to true OOP on mobile devices. This is a given since .NETcf supports the same IL assembler as .NET, which means you’re using the same Visual Basic .NET and Visual C# .NET languages as .NET, and not some stripped-down variant. With this CLS (Common Language Specification) compliance comes many code mechanisms and development benefits such as object calling, cross-language inheritance, and source-level debugging across different languages.
The bottom line is clear enough: There are so many features that are part of the common denominator here that it’s probably easier to say that a .NET feature is supported in .NETcf unless stated otherwise. Which brings us to the question: What is different?
.NET Framework: Compact/Desktop Differences
For starters, there is no ASP.NET in the .NET Compact Framework. This means you get none of the System.Web namespace aside from the client classes from System.Web.Services (calling XML Web services from mobile clients is supported). When you think about it, it kinda makes sense since very rarely will you want to host a full Web server on a Windows CE-based smart device.
A big bummer is that we get no COM interoperability, which means the compact CLR doesn’t include the COM marshaler from .NET that is able to translate inbound and outbound calls between .NET objects and COM objects. Windows CE does support COM and this limitation of .NETcf makes it difficult for your mobile code to “talk” to mobile COM libraries, such as the Pocket Outlook Object Model (POOM). COM Interop was omitted because of size and mobile resource considerations. It was important to keep the size of the mobile CLR down and COM Interop was simply too expensive. Your only way out of a .NETcf application domain is Platform Invoke (P/Invoke), which enables you to call Win32 DLLs in Windows CE, whether they are native or third party in nature. COM objects would then have to be “wrapped” using a native message-based DLL built with eVC++. This native wrapper would make all the COM interactions and your .NET application would talk to the wrapper through P/Invoke. Interoperability and COM Interop in .NETcf is too big a topic for the scope of this article, so I’ll come back to it in a future issue. Also, note that there is no support in .NETcf for writing a COM object.
The base class libraries are a subset of the full .NET Framework 1.0, bringing you roughly between 25% to 30% of the classes and functionality. It is important to note that this difference in compatibility goes all the way down to the method level. The same class might exist in both .NET and .NETcf, but it doesn’t mean the .NETcf version will have all the class members (properties, methods, or events) from the full version. Sometimes a class isn’t implemented at all, and sometimes it’s only partially implemented. Look up the documentation and IntelliSense to figure out what’s in and what’s out.
Another huge drawback is the lack of a .NET Remoting infrastructure to perform remote calls to server-side objects over HTTP or TCP/IP using binary or SOAP formatters. This is again because of size considerations since the Remoting infrastructure is fairly heavy on system resources. Client Web services calls are fully supported, and while the XML/SOAP overhead can be pretty costly when it comes to remote invocation over a wireless WAN connection that surfs at 30-40 Kbps, it remains your only high-level alternative. For more control and efficiency, you could build your own proprietary Remoting infrastructure using Windows Sockets in the System.Net namespace.
If you’re a fan of delegates (and you should be), note that while they work just fine in .NETcf, asynchronous delegates (i.e., BeginInvoke and EndInvoke methods) are not supported. This can be misleading since the documentation seems to indicate they work. Don’t be fooled, they don’t?even despite the presence of the two async methods in the Delegate class as reported by IntelliSense. Try as you might, even if you code it, the application will compile successfully but as soon as the CLR tries to enter the procedure containing the illegal code, a NotSupportedException will be thrown. Listing 1 shows such an excerpt of faulty code. All appearances lead to conclude this should work, but it doesn’t and Microsoft confirmed async delegates are not supported in .NET Compact Framework 1.0.
Because of the nature of the file system in Windows CE that differs from Windows NT-based systems, the .NET Compact Framework sports a different IO model. The primary consequence here is that you cannot capture file change notifications since none are fired by the operating system itself.
Don’t worry. We may be losing some things in the transition to the mobile world, but we are also gaining a few, such as the System.Net.IrDA namespace for programmatic access to the infrared port found in almost all Windows CE smart devices. This is a namespace that is exclusive to .NETcf and cannot be found in the full .NET Framework.
Additionally, here are some additional noteworthy features that are not supported or behave differently in the .NET Compact Framework:
The features noted in this section are by no means an exhaustive account of all the differences between the .NET Framework and .NETcf, but it gives you a fairly good idea to get started. Remember that experience counts just as much here as it does for desktop or server development, and with time, you’ll figure out what you can and cannot do in mobility projects and learn how to effectively design applications with these considerations in mind.
Exploring Namespaces and Classes
Even if those namespaces are supported, many are only partially implemented and have missing classes and members. There are also some namespaces that are missing altogether for various reasons.
Namespaces Lost, No Grief
Mourning for Namespaces
Compact Windows Forms
While eVB developers will certainly appreciate all the advanced controls available here, .NET developers will notice some favorites are missing, such as: