As you may have read in previous posts I've been using Wise Installer to create MSI files of our software for the PocketPC and Smartphone. However a deadline on Wednesday to go and demonstrate one of our applications and a still non-functional Wise installer led me to return to basics and get down and dirty with .CAB, .INF, .INI & .MSI's...and guess what? It's actually not too unbearable!
Starting on Tuesday afternoon I had a working MSI installer with custom actions and multi-cab install in about 4 hours. The problem with getting this stuff to work is that there really isn't a great overall guide to it all. I Googled a couple of links and used the MSDN Compact Framework FAQ and after reading through it all understood pretty much what there is to know and plugged it all together. These are the links I used...
The missing ingredient in all this how to install the cab files your application is dependent upon. To locate exactly what CAB files your application will need open the "Dependencies.PPC.txt" file that is created in the Cab folder under your project once you have run "BuildCab". Have a scan through, you'll see the other .CAB files pretty easily. So how do you get these into the .MSI?
private void CustomInstaller_AfterInstall(object sender, InstallEventArgs e)
{
string desktopFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// run WinCE App Manager to install .cab file on device
this.RunAppManager(desktopFolder, "OpenNETCF.ini", "YourApplication.ini");
}
private void RunAppManager(string desktopFolder, params string[] iniFiles)
{
// get path to the app manager
const string RegPath = @"Software\Microsoft\Windows\" +
@"CurrentVersion\App Paths\CEAppMgr.exe";
RegistryKey key = Registry.LocalMachine.OpenSubKey(RegPath);
string appManager = key.GetValue("") as string;
// build up the list of ini file arguments - each one needs wrapping in ""
string args = string.Empty;
for (int i = 0; i < iniFiles.Length; i++)
{
args += string.Format("\"{0}\" ", Path.Combine(desktopFolder, iniFiles[i]));
}
if (appManager != null)
{
// launch the app
//MessageBox.Show(appManager + "\n" + args);
Process.Start(string.Format("\"{0}\"", appManager), args);
}
else
{
// could not locate app manager
MessageBox.Show("Could not launch the WinCE Application Manager.");
}
}
This is the INI file for OpenNETCF. The text in red must match up and DO NOT have any spaces between the files and commas in the CabFiles list. The list below has a line break just for formatting sake but it should be all one continuous line.
[CEAppManager]
Version = 1.0
Component = OpenNETSDF
[OpenNETSDF]
Description = OpenNETCF SDF.
CabFiles = OpenNETCF.SDF.PPC3.ARM.CAB,
OpenNETCF.SDF.PPC3.ARMV4.CAB
This works really consistently (unlike Wise!) and I'm pleased with what I've acheived. I have plans for creating a Visual Studio.NET addin to run the CAB build and scan the Dependency file and automatically create the Setup Project with the right CAB and INI files in it for you but that's another story.
You can customise the installer using WinForms/.NET in the AfterInstall and Uninstall events so you can make the whole thing pretty slick. Have a go, it's not as tricky as it looks!
And to make it even easier these links tumbled out of the blog-sphere the day after I had done all this! DOH!
Starting on Tuesday afternoon I had a working MSI installer with custom actions and multi-cab install in about 4 hours. The problem with getting this stuff to work is that there really isn't a great overall guide to it all. I Googled a couple of links and used the MSDN Compact Framework FAQ and after reading through it all understood pretty much what there is to know and plugged it all together. These are the links I used...
- CodeProject - Packaging and Deploying PocketPC applications
- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/netcfdeployment.asp
- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcepb40/html/cxconcreatinginffile.asp
The missing ingredient in all this how to install the cab files your application is dependent upon. To locate exactly what CAB files your application will need open the "Dependencies.PPC.txt" file that is created in the Cab folder under your project once you have run "BuildCab". Have a scan through, you'll see the other .CAB files pretty easily. So how do you get these into the .MSI?
- Follow the instructions in the first link for adding a CustomInstaller and Setup Project to your SmartDevice solution.
- Create a .INI file for each .CAB mentioned in the Dependencies file (if you want to install it)
- Add the .CAB files to the Setup Project. The full path to each is in the Dependencies file.
- The secret ingredient...you can call the CEAppMgr (ActiveSync Add/Remove Programs) program with multiple .INI files on the command line parameter and it will install these one at a time.
private void CustomInstaller_AfterInstall(object sender, InstallEventArgs e)
{
string desktopFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// run WinCE App Manager to install .cab file on device
this.RunAppManager(desktopFolder, "OpenNETCF.ini", "YourApplication.ini");
}
private void RunAppManager(string desktopFolder, params string[] iniFiles)
{
// get path to the app manager
const string RegPath = @"Software\Microsoft\Windows\" +
@"CurrentVersion\App Paths\CEAppMgr.exe";
RegistryKey key = Registry.LocalMachine.OpenSubKey(RegPath);
string appManager = key.GetValue("") as string;
// build up the list of ini file arguments - each one needs wrapping in ""
string args = string.Empty;
for (int i = 0; i < iniFiles.Length; i++)
{
args += string.Format("\"{0}\" ", Path.Combine(desktopFolder, iniFiles[i]));
}
if (appManager != null)
{
// launch the app
//MessageBox.Show(appManager + "\n" + args);
Process.Start(string.Format("\"{0}\"", appManager), args);
}
else
{
// could not locate app manager
MessageBox.Show("Could not launch the WinCE Application Manager.");
}
}
This is the INI file for OpenNETCF. The text in red must match up and DO NOT have any spaces between the files and commas in the CabFiles list. The list below has a line break just for formatting sake but it should be all one continuous line.
[CEAppManager]
Version = 1.0
Component = OpenNETSDF
[OpenNETSDF]
Description = OpenNETCF SDF.
CabFiles = OpenNETCF.SDF.PPC3.ARM.CAB,
OpenNETCF.SDF.PPC3.ARMV4.CAB
This works really consistently (unlike Wise!) and I'm pleased with what I've acheived. I have plans for creating a Visual Studio.NET addin to run the CAB build and scan the Dependency file and automatically create the Setup Project with the right CAB and INI files in it for you but that's another story.
You can customise the installer using WinForms/.NET in the AfterInstall and Uninstall events so you can make the whole thing pretty slick. Have a go, it's not as tricky as it looks!
And to make it even easier these links tumbled out of the blog-sphere the day after I had done all this! DOH!
- EzSetup - free install builder tool. Got a plug on the MSDN Compact Framework Tips & Tips Webcast.
- Peter Foot of OpenNETCF blogged about this guys use of the NullSoft installer and his scripts to do multi-cab installs on the Smartphone.
Comments
Thanks James