Monday, January 4, 2010

Creating a Windows Mobile Device Center Bootsrapper for ClickOnce Deployment



The company I work for utilizes a mobile ordering management system that allows our sales force to visit our customers and create orders on an iPaq (A hand held "pocket" PC device that resembles an iPhone/iTouch, even though it was released years earlier). The iPaq is then docked at home or at the office and its orders transferred over the web as it syncs up.

In order to communicate with the iPaq, our application requires Microsoft Active Sync (if the user's host computer is WinXP) or Windows Mobile Device Center (If Vista/7). I need to know if my users are installing our M.O.M.S. updater app on a Windows XP or Vista/Windows 7 box.

I couldn't figure out a way to have ClickOnce determine if the users operating system was XP or Vista/7 (and 32 or 64 bit if the latter). After spending a lot of time searching Google, I found out that click once couldn't. My mission wasn't over just yet. I soon realized that creating my own Bootstrappers for custom prerequisites can, in fact, determine the OS (and processor architecture).

I'll assume you already know how to use Visual Studio. I am using Visual Studio 2008 for all of my examples.

If you haven't done so yet, create a quick ClickOnce program.

A great example can found here.


If you haven't done so already, download and install the Bootstrap Manifold Generator (BMG) which can be found here:
http://code.msdn.microsoft.com/bmg/Release/ProjectReleases.aspx?ReleaseId=1567

Start the BMG by clicking on Start->All Programs->Microsoft Visual Studio 2008->Bootstrapper Manifest Generator

You should now be at the start up screen which looks like the image below.


Click on File->New then choose Package Manifest. Press OK to continue.


Give your Project a name, I entered Windows Mobile Device Center.
The product Code is automatically filled in for you with periods replacing any spaces.

Above the left list box, there are two icons.
Placing your mouse above each one will display their intended purpose.

Lets click on the left one (Add install file).

I leave the default "All Languages" selected.

Browse to your WMDC installer.
If you don't have the WMDC installer file (drvupdate-x86), you can download it here.

Click OK to continue.



Properties




Enter the display name (Windows Mobile Device Center), this name will be displayed in Visual Studio prerequisite list.

The file name and language are carried over from the previous screen.

Below the language combo box, you will see various tabs.

The fields do not allow CTRL+V to paste in clipboard information. You have to right click then choose paste.

In the properties tab, there is a field titled "HomeSite URL".
Enter your location for your copy of WMDC that your users will be downloading if/when necessary.

I decided to keep a copy of the WMDC installer local on our server as Microsoft has changed things in the past and messed up our links.

Be sure to include the file name in the URL (including the extension).

In the Reboot Field, choose Defer. You shouldn't have to Reboot when installing WMDC, unless you have a copy of 6.0 installed and the setup file uninstalls it then installs 6.1.

You can get help for any of the remaining fields by clicking on them and hitting F1 on your keyboard.


System Checks
The next tab (System Checks) is where we add our checks to see if the WMDC is installed.
Most people (and examples) will choose to do a registry check. I'm going to show how to do a file check.

Click on the first icon located above the smaller listbox. If you hold your mouse over it, it should display "File Check". You should have a screen similar to the picture below.


The first box displayed is "Property for Result".
This is the variable name that you are giving. Enter "Application" in this box.
The next box is the file name that we are checking for. You can browse to the file or just type it in. The file name we are checking for is wmdc.exe

Check (if not already checked) "Start search in special folder" and choose Windows Folder. I've noticed that this drop down likes to resort back to Program Files folder when you leave the System Checks tab, so watch out for that. Yes, it has messed me up more than once :)

The path should be set to WindowsMobile (no space).
I leave the Search Depth set to 0.

Install Condtions


This is the place where our Bootstrapper does what our ClickOnce Deployment could not do.

We are going to determine if the user is trying to install this on XP, if so, bypass this Bootstrapper. We can also choose to fail for other conditions if needed.

Installation conditions are executed in the order listed. The first true condition stops the checks, so make sure you place them in their proper order. You can move them up or down in order at any time.

Bypass if processor architecture is 64bit
This version of Windows Mobile Device Center is for 32 bit operating systems.
We want to prevent this version from installing if the user's computer has a 64 bit OS.
Set the first drop down (Type) to "BypassIf"
The next drop down is Property, set that to "ProcessorArchitecture"
The next drop down is Comparison, set it to "="
The Value should be entered as "AMD64". Yes, even if it is an Intel :)

Bypass if user is on WinXP
WMDC is for Vista and Windows 7. WinXP uses ActiveSync, so we will need to bypass the install if the user's OS is WinXP.
Set the Type to "BypassIf".
Set the Property to VersionNT (make sure you pick VersionNT not Version)
Set the Comparison to Ver< (make sure you select Ver< style="text-align: center;">Bypass if WMDC version 6.1 or higher is already installed
This condition really isn't required, but we decided that we were going to force our users to upgrade if they are running version 6.0
Once again set the Type to ByPassIf
In Property drop down box, choose Version (This time its Version, not VersionNT)
Set the Comparison to Ver>= (make sure you select Ver>= and not just >=)
Set the value to 6.1

Exit Codes



We will be using 3 exit codes. You can add more if you wish.
Enter an exit code of 0 and a result of Success
Enter an exit code of 1641 and a result of Success, Reboot
Enter an exit code of 3010 and a result of Success, Reboot

Make sure the "Use Default System Exit Codes" is Checked and the Result is set to Fail.

That's it. That is all that we need for now. Click back to the System Checks tab and correct the special Folder to be WindowsFolder.

Let's build the Bootstrapper by clicking on the build icon (second icon on the very top of the first list box). You can also build by selecting Project then Build from the top menu.

If all is well, your build was completed without any errors and you now have a screen such a shown below:

By clicking on the build output link on top, you will be taken to My Documents\YourProjectName. So in this case mine is located in:
C:\Users\David\Documents\Windows Mobile Device Center

In this folder are 3items that were built:
a folder titled en
a copy of the WMDC installer
and product.xml


If you open Product.xml in notepad, you want to check your values in their appropriate section:
PackageFiles
PackageFile Name="drvupdate-x86.exe"
HomeSite="http://YourWebSite/YourFolder/drvupdate-x86.exe"

In the InstallChecks
FileCheck Property="Version"
SpecialFolder="WindowsFolder" <-This one gets me every time! ;) SearchPath="WindowsMobile" FileName="wmdc.exe" InstallChecks:
Commands Reboot="Defer"
Command PackageFile="drvupdate-x86.exe"

InstallConditions
BypassIf Property="ProcessorArchitecture"
Compare="ValueEqualTo"
Value="AMD64"

BypassIf Property="VersionNT"
Compare="VersionLessThan"
Value="6.0"

BypassIf Property="Version"
Compare="VersionGreaterThanOrEqualTo"
Value="6.1"

Exit Codes
ExitCode Value="0" Result="Success"
ExitCode Value="1641" Result="SuccessReboot"
ExitCode Value="3010" Result="SuccessReboot"
DefaultExitCode Result="Fail" String="Anunexpectedexitcodewasr" FormatMessageFromSystem="true"

Make sure Visual Studio 2008 is not open. If it is, close it.

Copy the complete folder that was created (C:\Users\David\Documents\Windows Mobile Device Center) over to:
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages

Just about everywhere that I have read tells me to copy it to:
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bootstrapper\Packages
That looks like the location of VS2005 on a WinXP development box.

But on my development box (Visual Studio 2008 on Vista) I had to place it in the first link.

If it doesnt appear in your ClickOnce Deployment list of prerequisites, close and restart Visual Studio.

THis is what the XML file looks like (except for the hash, which I shortened.)

xml version="1.0" encoding="utf-8" ?>
- <Product ProductCode="Windows.Mobile.Device.Center" xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper">
- <PackageFiles CopyAllPackageFiles="false">
<PackageFile Name="wmdc32_drvupdate-x86.exe" HomeSite="http://YourWebSite.com/SetupFiles/WMDC32_drvupdate-x86.exe" PublicKey="3082010A028201010037433DC30203010001" />
PackageFiles>
- <InstallChecks>
<FileCheck Property="Application" SpecialFolder="WindowsFolder" SearchPath="WindowsMobile" FileName="wmdc.exe" />
InstallChecks>
- <Commands Reboot="Defer">
- <Command PackageFile="wmdc32_drvupdate-x86.exe" EstimatedInstallSeconds="120">
- <InstallConditions>
<BypassIf Property="ProcessorArchitecture" Compare="ValueEqualTo" Value="AMD64" />
<BypassIf Property="VersionNT" Compare="VersionLessThan" Value="6.0" />
<BypassIf Property="Application" Compare="VersionGreaterThanOrEqualTo" Value="6.1" />
InstallConditions>
- <ExitCodes>
<ExitCode Value="0" Result="Success" />
<ExitCode Value="1641" Result="SuccessReboot" />
<ExitCode Value="3010" Result="SuccessReboot" />
<DefaultExitCode Result="Fail" String="Anunexpectedexitcodewasr" FormatMessageFromSystem="true" />
ExitCodes>
Command>
Commands>
Product>