I’ve recently jump through a number of hoops to put together an MSI
install package for a Mobile 5 application that uses the Compact
Framework 2.0. The goal was to provide a single file installation that
includes the CF2 install CAB and the CAB for our application.
Microsoft actually provides a very helpful MSDN article on "Deploying .NET Compact Framework 2.0 Applications with .cab and .msi Files"
(
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/deploy_cf2_apps_cab_msi.asp). There are just a few
things I’d like to add from my own experience.
1. Making your installer wait for ActiveSync to finish.
Part of the custom installation code you will be writing for the MSI
is code to launch ActiveSync to have it deploy the various CAB files
out to the connected device. The MSDN article provides good sample code
for this. The only problem I see with the sample code is that it fires
off ActiveSync and returns immediately. What this means is that your
MSI desktop installer process will finish and say it’s done with the
installation before ActiveSync has actually deployed to the device.
The fix for this is very simple. After launching ActiveSync simply
wait for the process to exit. In C# this would look something like
this:
System.Diagnostics.Process p =
System.Diagnostics.Process.Start({exe}, {args});
p.WaitForExit();
In C++ it takes a few more lines of code, but what you’d want to do is make a call to CreateProcess() filling in a
PROCESS_INFORMATION structure. Then make a call to WaitForSingleObject(). As a note,
I was unable to get CreateProcess() to work correctly until I gave it NULL for the exe and
simply passed in the entire command line via the command line argument.
2. Getting the installer to correctly deploy CF2 and then your own CAB.
In the MSDN article we are told that the INI file used to register
an application CAB with ActiveSync can contain multiple CAB files on
the "CabFiles" line.
"Line 7 enumerates all of the .cab files that are used for this installation in a comma-separated list."
This may work for installations that do not require a reboot of the
mobile device, but I was unable to get this to work for deploying CF2,
rebooting, and the deploying our application CAB. The solution I found
that works quite nicely is to actually launch the ActiveSync process
once for each CAB to be installed. So, in my case I created two
different INI files (one for each CAB) and then in my custom install
code I simply sequentially launch ActiveSync twice (once for each INI
file). So, my custom install code runs ActiveSync to deploy the CF2
CAB, waits for the process to finish, and the runs ActiveSync again to
deploy our application CAB.
3. C#, C++, and desktop dependencies.
The last quark I had to muddle through involved making sure that our
MSI installer did not create additional dependencies on the desktop
computer. The MSDN article provides all sample code in C#. If you code
your custom install actions DLL in C# you will be building a dependency
on the .NET Framework into your installer. In order to run the
installer the end user would be required to download all 20 some-odd
megabytes of the .NET Framework first!
So, I coded my DLL in C++ using the C# sample code as a guide.
Unfortunately, I built my C++ code using Visual Studio 2005. Why is
this unfortunate, you ask? Because C++ built in VS 2K5 uses version 8
of the CRT. Most machines will not have version 8, so VS 2K5
auto-detects this as a dependency and auto-includes the CRT v8 DLLs in
your installer. Cool... but wait.
The CRT v8 DLLs are considered "system components" and are installed
into the Windows system directories. Well guess what, only
administrators can do that. So, now, probably without even knowing it,
you have an MSI installer that can only be run by administrators and
can only be installed for "all users".
The solution is simple enough. Build your C++ DLL in an older IDE
(Visual Studio 2003 or Visual Studio 6 would work). You can then take
the already-built DLL and do the rest of the installer work in Visual
Studio 2005.
Good luck with those MSIs!
-Todd