When I was doing my first Pocket PC application I had quite a nightmarish experience with creating a setup package for my application. I was working in EVB. So to create a setup package I used the Application Install Wizard which comes with EVB. But when I was asked to customize the setup package like displaying my company name instead of the normal 'My Company', I knew that I was in trouble. All the time I was using this wizard and I didn't bother to look into what was going inside. Now I have some knowledge about creating Pocket PC setup packages especially using a command line tool called CabWiz.exe which comes bundled with Embedded Visual Tools, which I want to share with you guys who are just entering into the world of Pocket PC development.
At the end of this article you will know
- What is a cab file?
- What is Cabwizard tool?
- How Cabwizard generates application setup cab files?
- How to generate a simple Pocket PC setup package using Cabwiz.exe?
What is a Windows CE .cab file?
- Created by compressing application files, dependencies like dynamic link libraries, images, registry entries etc.
- Processed by an executable called wceload.exe present in \windows directory of Pocket PC emulator / device.
What is Cabwizard tool
- Is an executable called CabWiz.exe.
- Is used to generate Application setup packages as a Windows CE .cab file.
- Comes as part of Embedded Visual Tools 3.0 and Visual Studio .NET 2003 with Smart Device extensions.
- Used by Embedded Visual Basic 3.0 and Visual Studio .NET 2003 with smart device extensions to generate application setup packages.
What are the inputs taken by Cabwizard to generate .cab files ?
- Version details of the application and other details like name of application, company name etc.
- Hardware platforms targeted (MIPS, X86, ARM, SH3).
- Source path of application files and dependencies in desktop machine.
- Names of Application files and dependencies to be taken from source path given.
- Destination path in Pocket PC emulator / device where application files and dependencies are copied.
- File properties or action flags if required, to be set for application files in the device.
- Shortcuts, if any, to be created in the Pocket PC emulator / device for the application.
- Startup and cleanup actions, if any, to be done when the application is installed/uninstalled.
- Registry entries, if any, used by the application.
- COM objects to be registered in the Pocket PC emulator / device.
These inputs specified above are taken by the Cabwizard tool in the form of a .inf file, and using these inputs, Windows CE .cab files for the hardware platforms targeted are generated. The command line syntax of Cabwizard tool is:
cabwiz.exe <INF_FILE> [destination dirs of .cab files]
[error log] [/cpu target_platform1 [target_platform2]]
.inf file containing the application installation details.
destination dirs of .cab files
Destination directory of .cab files. If no directory is specified, .cab files are generated in the
File for logging errors and warnings encountered during compilation. If no file is specified, errors and warnings are displayed in message boxes.
Creates a .cab file for each platform label specified. The labels given should be the labels used in the .inf file.
cabwiz.exe "c:\myfile.inf" /err myfile.err /cpu sh3 mips
What's a .inf file
- A .inf file is like a .ini file containing various sections, keys and values which contains information needed by Cabwizard tool to generate cab files.
- The presence of some of the sections is mandatory in the .inf file. For more details regarding the sections, please refer here.
The following are the various sections present in the .inf file.
Contains application creator and version details.
Contains string constants for application and directory names used by other sections.
Contains string constants for one or more strings used by other sections.
Platforms for which application is targeted.
Specifies individual installation tasks like install shortcuts, copy common files to \windows directory, copy application files to application directory etc.
Specifies the directories of application files and its dependencies in the desktop machine. This is used by the Cabwizard to retrieve the application files and dependencies to generate .cab files.
Specifies the application files and dependencies. The Cabwizard uses
SourceDisksFiles sections to retrieve the application files and dependencies to generate .cab files.
Directive to copy files in the device.
Contains Registry entries, if any, used by the application.
Shortcuts, if any, to be created for the application in the Windows CE device.
A simple example:
The best way to understand a concept is work it out. So, we will try a small example to understand this concept a little better. For the benefit of understanding, I have kept this example as simple as possible.
We will write a small EVC application and try to write a setup package for it. EVC? Yeah, you heard it correct. But don't worry it's a very simple program.
Probably after finishing this article, you can create a small EVB project and try using EVB application wizard to generate the setup package for your EVB application. At the same time, you can take a look at the .inf file generated to get a better idea of the process. If you know how to fiddle with the .inf file generated by the EVB application wizard, you can modify and use it for EVC applications too.
Ok. Let's start. Let's use EVC 3.0 for now. For the purpose of understanding, I'm assuming that the path of our example application is C:\.
Creating a WIN32 API application
- Start EVC 3.0,
- Select File = > New = >WCE Pocket PC 2002 Application.
- Set project name as test2002install.
- In Step 1, select 'An empty project', click Finish.
- An empty project is created. Select File = > New = > C++ Source File.
- Give the name of the source file and click the OK button. A .cpp file is opened.
Type the following lines in the file:
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE hprevinstance,LPTSTR lpcmdline,int nshowcmd)
MessageBox(0,TEXT("test 2002 installation"),0,0);
What does the application do?
The application displays a message box with text 'test 2002 installation'.
Compiling the application
- Select Build => Set Active Configuration.
- Select Win32[WCE x86 Release]. Press OK. (compiling application for X86 platform)
- Compile the project by pressing F7 key or Build => Build test2002install.exe.
- Again, select Build => Select Active Configuration. Select Win32[WCE ARM Release]. Press OK. (compiling application for ARM platform)
- Compile the project by pressing F7 or Build => Build test2002install.exe.
Hopefully, your project is compiled without any errors. For those of you who are new to EVC, we just compiled our program for ARM and X86 platforms. But why twice? Since we are dealing in native code now, we have to compile our program for different platforms being targeted, unlike EVB and .NET Compact Framework.
For this example, we will target ARM and X86 platforms. So, this application will run only on Pocket PC emulator and Pocket PC devices running ARM processor.
To run the program in the emulator, ensure that build configuration is Win32[WCE x86 Release] by going to Build => Set Active Configuration and selecting Win32[WCE x86 Release] option. Build the program by selecting Build => Build test2002install.exe. Run the program by selecting Build => Execute test2002install.exe
OK. Our EVC application is ready. Now, we go to the EVC application directory, i.e. C:\test2002install. There we can see directories like ARMDbg, ARMRel, X86Rel etc. These are the directories for platforms for which our application have been compiled. Directory names ending with Dbg contain the debug version of the application and Rel contain the release version. We will consider X86Rel and ARMRel for this example.
Generate .inf file
Start Notepad. Open a new document.
First, we will set the string constants for application names and application install directory which will be used in other sections. For this, we need to set the
[CEStrings] section as follows:
%CE1% is a predefined directory constant for \Program Files. For a list of predefined directory constants, please refer here.
Appname, if we are using any other string constants, we can define them under
So, we have set all string constants needed by us. Next, we will set the version info of the application, for which we will be using the
[Version] section. This section has 3 mandatory keys -
Provider. The values of
Signature will be
"$Windows CE$" and
"$Chicago$" respectively. For
Provider key, we assign the
CompanyName string constant which we defined above.
Next, we will add the shortcuts of the application. We will be adding them under the section
[Shortcuts]. The entries will be in the format:
Name of the section. We are using
Shortcuts as the name.
Name of the shortcut file.
Numeric value telling whether shortcut is to a folder or a file. Zero or empty means shortcut is to a file. Any non zero value represents shortcut to a folder.
File /path where the shortcut points to.
Optional string value giving the path where the shortcut file will be created. If empty, path given in
[DestinationDirs] section is used.
In our case, we need one shortcut in the start menu for the application. We won't be giving the
%AppName% is the predefined string constant containing the name of the application.
Next, we will give the source path of our application files and dependencies in the desktop machine from which the Cabwizard can retrieve the files for processing. For that, we will be using
[SourceDiskNames] section. Talking about the application files and dependencies, all the .exe and .dll files are platform specific, while images, registry entries, configuration settings files etc. are not platform specific files.
While giving the source paths under
[SourceDisksNames] section, we can follow two approaches:
- The first approach is to give all the source paths under a single
- The second approach is to use multiple
[SourceDisksNames] sections to specify the source paths of platform specific and non platform specific files.
The second approach is more modular in nature especially when there are a large number of application files and dependencies. In our example, we will be following the second approach. While giving the source paths of platform specific files, we can specify the label of their platform like
[SourceDisksNames.X86] for our reference. As for labels, we can give anything as long it's same across the .inf file and in the
/cpu argument of Cabwizard tool.
Here is the format of
[SourceDisksNames] section entry.
Unique identifier for a source path.
Description of the path.
Path in the desktop computer where the application files / dependencies are stored. It can be absolute or relative.
Label for the particular platform like ARM, X86 etc.
In our case, we don't have any platform independent files as the executable is a platform specific file. So, we will give the paths of ArmRel and X86Rel directories under
[SourceDisksNames.X86] like this.
Next, we will give the names of application files to be taken from source paths which we gave using
[SourceDisksNames]. For that, we will be using
[SourceDisksFiles] section. Like how we did for
[SourceDisksNames], we will include names of non platform specific application files in
[SourceDisksFiles] section and names of platform specific application files under the corresponding
[SourceDisksFiles.XXX] section for the particular platform, where
XXX is the label for respective platforms like ARM, X86, SH3 etc. The entries will be in the format:
Name of the application file or dependency.
path_id used in the corresponding
Sub directory path of the file. This value is optional.
Label for the particular platform like ARM, X86 etc.
In our case, we need to include only the application executables compiled for ARM and X86 platforms.
Up to now, we have given the following inputs in the .inf file
- Source paths of application files and dependencies in desktop machine.
- Names of application files and dependencies.
- Version information of application.
Now, we will give the following inputs in the .inf file
- File properties or action flags to be set for application files and dependencies when they are copied to device.
- Destination paths of application files and dependencies.
- Install tasks to be done.
To set the file properties, we can specify all the application files under one section and give the properties to be applied. But for the purpose of modularity, especially when there are number of application files and dependencies, we can segregate them under different sections like
[Files.X86] etc., based on their platform specific nature. The labels given to indicate various platforms must be the same across the .inf file. The entries can be in the format:
Name of the file given in the device for a particular device.
Optional name of the source file.
File properties or action flags to be set while file is being copied to device. For action flags or file properties supported by Windows CE, please refer here.
If names of destination and source files are same,
Source_Filename can be omitted. In our case, we have only the application executables compiled for ARM and X86 platforms, we segregate them under
[Files.X86] sections respectively.
For the sake of simplicity, we won't specify any file properties or action flags for our application files. If there are no action flags, files will be copied with default properties or flags in the device.
Now, we will need to give the destination directories to which the application files will be copied in the device. For that, we will use the
[DestinationDirs] section. The entries will be in the format:
In our case, we won't be giving
DefaultDestDir entry. The other entries will go like this:
Here, we are telling to:
- Copy shortcuts to \windows\start menu folder.
- Copy files under
[Files.X86] sections to application install directory.
%CE2% is the predefined directory constant for \windows directory. For a list of predefined directory constants, please refer here.
We have given the destination directory path for our application files and dependencies. All the section we defined were like defining sub routines in our program. Just by defining sub routines, the program will not call them. Only after we call our sub routines in the main function, they will get called. Like that, we will be writing the main routine as far this installer is concerned.
[DefaultInstall] section which specifies the installation tasks to Cabwizard is the main routine as far as the installer is concerned. Here, all the sections defined are integrated. The contents of the sections are used as input to install the application in the device. Again, for the sake of modularity, we can segregate the installation tasks to various
[DefaultInstall] sections based on the platform specific nature of our application files. The entries can be in the format:
Assigned with name of sections listing application files. During execution, the files listed under file sections are taken and copied to the path given for that section name in the
[DestinationDirs] section. While copying, file properties or action flags if specified are applied to the particular file.
Assigned with Registry sections containing registry entries used by the application.
Assigned with name of section containing application shortcuts.
Assigned with name of a WIN32 DLL exporting some symbols called by Windows CE during installation/un-installation of the application.
Assigned with name of COM DLLs used by the application to be registered in the device.
The non platform specific files of the application like images, registry entries, shortcuts can be included under
[DefaultInstall] section, while the platform specific files of application like executables, COM DLLs, Application setup DLL can be included under the corresponding
[DefaultInstall.XXX] section where
XXX is the label of the platform like ARM, X86, SH3 etc. We will discuss
CESelfRegister keys in the forthcoming parts of this article and ignore them for now. In our case, the entries will go like this.
That's all. We have created the .inf file.
Here is the file created for your reference:
Generate cab files
Now we will invoke the Cabwizard tool with the path of the .inf file as argument. Since we have used 'Arm' and 'X86' as labels for corresponding platforms throughout the .inf file, we will use the same in the
/cpu argument of the Cabwizard tool. Here is the command line with the assumption that Embedded Visual Tools is installed in D:\program files directory.
"D:\Program Files\Microsoft eMbedded Tools\EVB\cabwiz.exe"
"c:\test2002install\test2002install.inf" /cpu "X86" "Arm".
If everything executes correctly, we should be able to see 2 cab files - test2002install.Arm.cab and test2002install.X86.cab in the c:\test2002install directory.
Testing .cab files
We can try to install the .cab files on either Pocket PC emulator or device. For Pocket PC emulator, we should take the .cab file generated for X86 platform. For Pocket PC devices running ARM processors, we can use the .cab file generated for ARM platform. To install the .cab file, just copy the appropriate .cab file in emulator or device and click on it. To uninstall the application in the device, go to Start => Settings => System => Remove Programs, Select ABC Company test2002install and click the Remove button. I tested the .cab files successfully with Pocket PC 2002 and 2003 emulators.
Even though the whole business of using Cabwizard tool to generate application setup packages may seem somewhat complex, if you know how to use it you can implement lots of features in setup packages like custom actions etc. Hope this article was useful in understanding the functionality of Cabwizard a little better. Please give your valuable suggestions (positive or negative) on this article.