Thursday, January 14, 2010

Setting up VS2008 For Windows Mobile 6.1 Development

There are a few tricks to setting up your PC for Windows Mobile 6.1 Development that are needed to get moving.  Of course some of this will depend on exactly what you want to do in Windows Mobile.

My project was pretty simple.

  1. Create a Windows Mobile Forms app that interfaces with a Motorola M9090-G scanning device that allows a user of the scanner to scan their employee badge barcode, a barcode for a shipping document, and a barcode for a series of packages.
  2. The user will scan a large number of packages, and then send their scan records in a batch to a central database for further processing.  The user may or may not be close to a wireless access point at the time of the scan.
  3. The app has to be fast.   The folks using this device will fly through dozens of packages a minute, and there will be multiple scanners working to unload a truck, but there are logical gaps in the loading and unloading where the app can upload to the database.

It’s pretty obvious I needed a client cache for the data.  I chose Microsoft SQL Server CE.  For the backend data store, we’re using SQL Server 2008 (with Change Tracking turned on)

I didn’t want to custom build a synchronization methodology, and since I played with Microsoft Sync Services a bit last spring on another project, it seemed like a good place to start.

First off, VS2008 SP1 comes with a number of emulators built in, but no Windows Mobile 6 emulators.  In order to get the right emulators installed, download the following, and install in the following order.  You’ll need to shut down VS2008 to complete this install.

  1. Windows Mobile 6 Profession and Standard Software Development Kits Refresh
  2. Windows Mobile 6 Professional Images (USA).msi
  3. Microsoft Windows Mobile Device Center Driver
  4. Microsoft SQL Server CE for Devices
  5. Microsoft Synchronization Services for ADO.NET for devices – note that you cannot user Sync Services 2.0, as it is not device ready yet.

You should now be able to fire up VS2008 and create a new Smart Device Project.  Make sure you set it up for Windows Mobile 6, or you’ll not have all the options you need, and will have to start over.

One mistake I made, was not realizing that there is a different version of Microsoft SQL Server CE for Devices than for PCs.  You will need to download the correct version to get everything to work.

I strongly suggest creating two solutions for this type of an application.  One for the Mobile client, and one for the WCF Service, whether it be a Windows Service or a Web Service.  It makes it a lot easier to debug, and helps to ensure that you don’t try to deploy Mobile targeted assemblies to the server and vice versa.  The IDE should prevent you from doing it, but it doesn’t hurt to take this approach anyway.

I like writing code, but I like getting projects done even more.  So if I find code out there that works, I’m not afraid to put it to use.  There were a couple of projects I found that really help to do some of the heavy lifting:

  1. SyncComm on Codeplex.  This provides you with all the plumbing you need to get Windows Mobile Sync working in your project.  If there is one thing I would change (and did) in the project, it was to break the ClientService.cs up into another partial class to remove the customizations that were done to it.  I have found three methods that I moved into a separate file.  Otherwise the code gets wiped out when you regenerate it.  Cost me an hour of work.  See code below.
  2. Custom Message Encoder: Compression Encoder on MSDN.  Download the sample there.  The download link is trickily hidden under the title of the article.  This provides you with all kinds of samples.  The one you want to go to is under <installroot>\WCFSamples\WCF\Extensibility\MessageEncoder\Compression\CS.  Take the GZipEncoder and add the project to your server solution.
public ServerClient(System.ServiceModel.EndpointAddress endPointAddress, BindingType bindingType)



        : this(GetBinding(bindingType), endPointAddress)



    { }



 



    static Binding GetBinding(BindingType bindingType)



    {



        Binding binding;



 



        switch (bindingType)



        {



            case BindingType.Basic:



                binding = CreateDefaultBinding();



                break;



            case BindingType.Compressed:



                binding = CreateCompressionBinding();



                break;



            default:



                throw new ArgumentException("BindingType value not excepted");



        }



 



        return binding;



    }



 



    //NOTE:



    //set compressed endpoint binding custom properties here



    public static Binding CreateCompressionBinding()



    {



        // Create a CustomBinding



        var customBinding = new CustomBinding();



        // Create a compression binding element



        var compressionBindingElmnt = new CompressionMessageEncodingBindingElement();



        // ..and add to the custom binding



        customBinding.Elements.Add(compressionBindingElmnt);



 



        // Create an HttpTransportBindingElement and add that as well



        var httpBindingElement = new HttpTransportBindingElement();



 



 



        //TODO



        //Set here desired values. Take care to match such values 



        //in app.config in SyncComm host project



        //max buffer size



        //httpBindingElement.MaxBufferSize = int.MaxValue;



        //max received message size



        //httpBindingElement.MaxReceivedMessageSize = long.MaxValue;



        //max buffer pool size



        //httpBindingElement.MaxBufferPoolSize = long.MaxValue;



 



        customBinding.Elements.Add(httpBindingElement);



 



        return customBinding;



 



    }




In order to get WCF to connect from the Windows Mobile 6 Emulator to a Web Service on the local host, you’ll need to follow the steps listed by Chris Brandsma on StackOverflow.  This is critical and can cause a lot of frustration if you don’t do it.



So as of today, I have a client on my Windows 6 Emulator, a Web Service, and the basic data flowing, though I have a lot of work left to do to test and refine the processing, and to test on an actual device.  I’m sure I’ll find a few more issues, but I wanted to note what I had done to this point, just in case I need to replicate the process on another PC or build server here in the near future.



Let me know if this doesn’t work for you.

No comments: