Archive for the ‘Installation’ Category

A much better way to side deploy WM6.5 widgets

Monday, October 12th, 2009

Picture of a sad smiley faceSometimes I can be a bit of a dope…

You can ignore my previous post about side loading widgets which are deployed via a web server… There’s a much easier way.. the entire post was based upon incorrect assumptions and feedback from a couple of people with actual WM6.5 devices (hacked XDA-developers.com based ROMS no less…).

I’ve since discovered that most widgets should automatically install (without hacks) if you simply provide a hyperlink to the *.widget file directly. Although the crappy internet explorer dialog with less than obvious “open” option is still part of the installation process which may trip up less technology savvy users (or at-least require additional guidance on the download page).

Depending upon your webserver you may need to alter your mime types however to get the file correctly detected. If this is the case, add an entry for the .widget file extension with the mime type specified as “application/widget”.

Gerr… sometimes it really pains me the lack of developer documentation and support for WM6.5. This is not the first time I’ve gone down incorrect paths.

If you have access to an actual WM6.5 device with non hacked ROM, I would love for this to be verified. I’m sick of second guessing emulator behavior vs actual released ROM behavior.

Deploying WM6.5 Widgets from your own webserver

Monday, October 12th, 2009

UPDATE: THIS ENTIRE POST IS BOGUS – CLICK HERE FOR A MUCH EASIER WAY

Screenshot showing main window of Widget Packager utilityBy default Windows Mobile 6.5 widgets must be distributed via the Windows Marketplace for Mobile. Although you can host your *.widget files on a webserver of your choice the OS will refuse to install them without setting a couple of registry settings on the device.

There is a possible work around for this situation however… and that is packaging up your *.widget file inside of a *.cab file, as the web browser already knows how to download and install those. The challenge with this approach then becomes how to conveniently build the CAB file which will auto-magically install your widget.

Introducing Widget Packager

UPDATE: THIS ENTIRE POST IS BOGUS – CLICK HERE FOR A MUCH EASIER WAY

Widget Packager is a small utility I have developed which can run on your development desktop machine. Once you have developed your WM6.5 widget, you simply drag and drop the resultant *.widget file onto the widget packager main window and you will be prompted to save a matching CAB file.

Place this CAB file on a correctly configured webserver and you are ready to post a link within the mobile version of your website. Anyone that clicks on the link within Internet Explorer for Mobile will be prompted to save or open the file.

Opening the CAB file (or saving it and selecting it within File Explorer at a later date) will cause the standard widget installer to launch to install your new widget. Once installed no trace of the CAB file (such as an entry within the remove programs list) can be found.

As an example, use the web browser on your mobile device to install the following MobileFlashlight widget that I have packaged as a cab file. This should demonstrate the installation process, but don’t take it as a good example of widget design. It was simply the first *.widget file I grabbed while developing this proof of concept.

Limitations of this approach

UPDATE: THIS ENTIRE POST IS BOGUS – CLICK HERE FOR A MUCH EASIER WAY

The dynamic creation of a CAB file, and the installation of widgets from an arbitary webserver is a cool demo, but is it really worth the effort? At this stage I’m not sure it really is. Potential problems with this approach include:

  • The CAB file is unsigned – The CAB file (and a setup.dll within it) are unsigned. This means some devices may refuse to install it, or atleast display warning prompts. In order to resolve this you would need to sign the CAB with a Mobile2Market certifcate which is probably more expensive than the Windows Marketplace for Mobile process you are trying to avoid.
  • Lack of upgrade mechanism – You would need to develop your own solution for detecting and installing updates to your widget, as obviously you can’t rely upon the marketplace for these features.
  • WM6.1+ has a “feature” – Since WM6.1 a feature or bug depending upon your viewpoint means if you create a CAB file and configure it to leave no uninstallation information the OS still detects it when the CAB file is re-ran. This means the user is prompted to uninstall the previous version, and even worse, since no uninstallation information is available the uninstall fails. This isn’t a road block (as the user simply needs to tap “Yes” twice), but it’s not exactly a great user experience either if you attemp to upgrade your widget.
  • Internet Explorer’s open/save file dialog sucks – The file save dialog in Pocket Internet Explorer was never that nice, but in WM6.5 it’s a case of one step forwards, two steps backwards. Now it is full screen, but the options are hidden away within menus… As a small hint, you’ll find the “open” option within the menu that pops up when you click the “Menu” softkey. Why they don’t use all that whitespace within the dialog to display two big finger friendly graphical buttons is anyones guess…

So is it really worth it? I’ll let you be the judge of that. One case where it may be useful, is if your widget needs the use of an ActiveX control which needs to be installed as part of the widget installation process. *.widget files don’t support that particular feature, while the Widget Packager could easily be extended to support that.

Download the utility

UPDATE: THIS ENTIRE POST IS BOGUS – CLICK HERE FOR A MUCH EASIER WAY

[Download WidgetPackager.zip - 197KB]

If you’re interested in trying out the utility, it is available for download. The ZIP file includes the utility, as well as an example *.widget. There are three ways to run the utility

  • Run the WidgetPackager.exe GUI, then drag and drop a *.widget file from file explorer onto the main window. You will be prompted for a CAB filename, and it will then be generated.
  • Place a shortcut to WidgetPackager.exe on your desktop or quick launch toolbar etc. Drag a *.widget file onto this icon and a *.CAB will appear in the same location.
  • Call WidgetPackager.exe from the command line (perhaps as part of an automated build process). Simply specify the name of the *.widget file as a command line parameter and optionally the path for the CAB file (will default to naming the CAB the same as the *.widget file).

For those that are interested the source code for the utility is also included. Perhaps of most interest to developers is the way in which the *.CAB file is built programatically (without the use of cabwiz.exe). This will be the topic of a future blog post.

Is this utility of use to people? Some of the limitations and loose ends (such as no warning if attempting to install on a Windows Mobile 5.0 or 6.0 device) could be resolved with a little more effort and hacking if there was demand.

UPDATE: THIS ENTIRE POST IS BOGUS – CLICK HERE FOR A MUCH EASIER WAY

Making a CAB file which doesn’t prompt for installation location

Thursday, December 11th, 2008

Screenshot showing application being installed on a Windows Mobile deviceWhen developing bespoke line of business applications it is common for your solution to require some form of hard reset recovery.

A common technique for implementing this is to package the application as a CAB file and then use a device specific technique to ensure that this file survives and automatically installs after a hard reset.

One problem you may come across in implementing this scenario is that a Smart Device CAB project created by Visual Studio will by default prompt the user to select where to install the application if one or more storage cards are present. This blog post covers one technique to remove this prompt when you want to reduce user interaction and need to hard-code the installation location of your application.

Finding an explanation

The first step towards finding a solution is to determine the reason why we are seeing the current behaviour. We can find an answer within the User Selected Installation section of the CAB Wizard documentation available on MSDN. This document states the following:

The user is prompted for the preferred installation volume only if the following two conditions are met:

  1. The application developer has created an %installdir% variable in the [CEStrings] section of the .inf file.
  2. The device has more than one storage volume available (such as a secondary MultiMedia card storage).

We obviously can not control the number of storage volumes present on a user’s device, but what is an *.inf file and how can we control the content of it’s [CEStrings] section?

Manually rebuilding a CAB file

The Smart Device CAB project type within Visual Studio is a simple GUI front end to a command line utility called CAB Wizard (cabwiz). When Visual Studio builds your project it takes the settings you have specified and behind the scenes generates a specially formatted text file (an *.inf file) which instructs the command line utility how to create your application’s CAB file.

Unfortunately for us the Visual Studio IDE always includes an %installdir% variable within the [CEStrings] section of the file it generates and there is no option that allows us to override this behaviour.

One possible work around to remove this variable is to allow Visual Studio to generate it’s *.inf file and then manually edit it and re-run the cabwiz utility by hand.

First we need to determine where the *.inf file is stored and the proper command line required to execute cabwiz.exe. This information can easily be found by looking at the Output Window of Visual Studio after you build your solution. Near the end of the log you should see a section that looks similar to the following:

------ Build started: Project: BespokeLOBApplicationCAB, Configuration: Debug ------
Building file 'C:\BespokeLOBApplicationCAB.cab'...
 
"C:\Program Files\Microsoft Visual Studio 9.0\smartdevices\sdk\sdktools\cabwiz.exe"
    "C:\Project\BespokeLOBApplicationCAB.inf"
    /dest "C:\Project\"
    /err CabWiz.log
 
Windows CE CAB Wizard

If you open the inf file specified in the above command line you should be able to find and then delete a line declaring the %installdir% variable (as highlighted in the screenshot below).

Screenshot showing the line which needs removed from the CAB's *.INF file

Once you have saved this change the last step is to open a MSDOS command prompt window and execute the command line discovered above to re-generate your CAB file. This new CAB file won’t prompt for an installation directory due to the lack of the %installdir% variable.

One thing to be aware of is that removing the %installdir% variable means placing files in the “Application Folder” directory within the File System Editor window will cause an error when you run cabwiz. Instead you should build up your directory structure by hand by right clicking in the file system editor and selecting the option to add new Custom Folders.

Sample Application

[Download BespokeLOBApplication.zip - 18.1KB]

A small sample application is available for download which demonstrates this technique. A “dummy” application called BespokeLOBApplication is packaged into a CAB file via a Smart Device CAB project.

Notice if you build the CAB via the Visual Studio interface that the user will be prompted to select an installation location even though every file specified in the filesystem editor is deployed to a hard-coded location.

If you then alter the CAB file using the technique outlined above the user will not be prompted to select an installation location during installation.

For your convenience the download also contains two pre-built cab files called BespokeLOB_Prompt.cab and BespokeLOB_NoPrompt.cab to demonstrate the principal.

One disadvantage of this technique is that manual edits to the *.inf file will be lost the next time you rebuild your project via Visual Studio. If the structure of your CAB file does not change that often one solution is to remove the Smart Device CAB project from your solution and instead build your CAB file by executing the command line discovered above via a custom Post Build step.

What’s wrong with my product name? Why special characters need not apply.

Monday, June 23rd, 2008

Recently while porting another subset of Chris Craft’s 30 Days of .NET applications to C++ I came across another example where the Visual Studio Smart Device CAB deployment functionality has a small trap that could trip up developers new to the tool, and it all depends upon the name you choose for your product…

Day 10 introduced an application named “What Is My IP?“. While creating the CAB file to deploy this application I followed Chris’s lead and set the Product Name to “What Is My IP?”, as shown in the screenshot below.

Screenshot showing Product Name property for CAB file

Everything compiled without error but when I went to install the CAB file I was greeted with the following error message:

Screenshot showing Windows Mobile device failing to install CAB file

Alternatively in some circumstances I could install the application, but uninstallation would fail without removing a single file or shortcut!

The Problem

In a previous blog post I discussed the internal structure of Windows Mobile CAB files. It turns out the problem is to do with the question mark at the end of the product name.

The Visual Studio Smart Device CAB Deployment project also makes use of the Product Name as the default installation directory. Within the *.INF file produced behind the scenes you will find a section similar to the following.

[CEStrings]
AppName="What Is My IP?"
InstallDir=%CE1%\%AppName%

When this file is processed to produce a CAB file, the _setup.xml file within the CAB will contain the following XML snippet:

<parm name="InstallDir"
      value="%CE1%\What Is My IP "
      translation="install" />

Since a question mark is not a valid character for a directory name it has been replaced with a trailing space. It seems this additional space is enough to trip up something within wceload.exe, the executable responsible for installing CAB files on Windows CE based devices.

The Solution

The only solution I’ve been able to come up with is to ensure that your product name does not end in a character that is not valid for a directory name. In this example I renamed the Product Name to “What Is My IP”.

Another alternative is to manually create your CAB file by writing your own *.INF file. By doing this you will be able to default the installation to a directory which isn’t mapped 1 to 1 to your Product Name.

How to avoid hardcoding file paths within CAB file registry settings

Monday, February 4th, 2008

Screenshot showing Registry Editor window within Visual Studio

Sometimes when building a CAB file it is desirable to add registry values that refer to the location of files installed as part of the application. For example a document orientated application may configure file association registry entries that need to specify the location of the main executable.

The problem with hard-coding a registry value such as “\Program Files\MyApplication\MyApplication.exe” is that it breaks if the user chooses to install the application onto an SD Card, or the directory “\Program Files” is localised into some other name on a non English device. Ideally we would specify the registry value in such a way that it automatically adapts itself as part of the installation process. We can actually achieve this…

The Smart Device CAB project type within Visual Studio is a wrapper around the cabwiz.exe command line application. Behind the scenes the Visual Studio IDE takes all the settings you configure graphically, produces an *.INF file and passes it through cabwiz.exe. This means that the Visual Studio IDE supports many of the “power features” of the underlying tool.

One of these “power features” is the concept of Macro Strings. If you specify a registry value to be a string that contains the %InstallDir% macro the CAB installation process will automatically replace the %InstallDir% part of your string with the user’s specified installation directory.

As well as %InstallDir% there are a range of other macro strings which can be utilised as summarised in the table below:

Macro Substitution on English devices
%InstallDir% [directory application installed into]
%AppName% [name of application]
%CE1% \Program Files
%CE2% \Windows
%CE4% \Windows\StartUp
%CE5% \My Documents
%CE8% \Program Files\Games
%CE11% \Windows\Start Menu\Programs
%CE14% \Windows\Start Menu\Programs\Games
%CE15% \Windows\Fonts
%CE17% \Windows\Start Menu

Incidentally this feature is also the cause for a possible error message you may run across if you attempt to specify a registry value that contains an embedded % character…

“The Windows CE CAB Wizard encountered an error. See the output window for more information.”

Error: unsupported DirID 0
Error: File c:\xyz.inf contains DirIDs, which are not supported

This cryptic error message results from cabwiz.exe attempting to interpret the % character as a macro string. The solution to this problem is to escape single % characters with a second %. For example the value “100%” needs to be specified as “100%%”.

How to determine where an application is installed

Monday, December 10th, 2007

Screenshot showing a messagebox describing where the application is installed on the filesystemMost Windows Mobile software is installed via the use of a CAB file. On recent versions of the Windows Mobile operating system CAB Files offer the user the choice of where to install the application. However numerious system APIs and features require the full path to the application’s executable to be specified.

This blog entry discusses how a .NET Compact Framework application can determine its installation location for use in such APIs.

How to determine the full path to the executable

using System.Reflection;
 
private string GetApplicationExe()
{
  // Determine the full path to the application executable
  return Assembly.GetExecutingAssembly().GetName().CodeBase;
}

The GetExecutingAssembly method returns an Assembly object that represents the Assembly that contains the code which called the GetExecutingAssembly method. Hence if this call is placed within code contained within the main executable it will return the path to the main executable.

An example return value may be “\program files\foobar\foobar.exe”. This value is useful to have for APIs such as SystemState.EnableApplicationLauncher which expect the full path to our executable to be specified. By not hard coding the path within our application we allow the end user to move the application around on their device without breaking the application’s functionality.

How to determine the directory containing the application
It is common for an application to install a number of configuration or data files required by the application. Since Windows CE does not have the concepts of a current working directory or relative paths full paths need to be specified when attempting to access these files.

By using the Path.GetDirectoryName static method we can extract the directory component of the path obtained above, so that we do not need to hard code the location of our support files.

using System.IO;
 
private string GetApplicationPath()
{
  // Return the full path to the directory our
  // application is installed within.
  string codebase = GetApplicationExe();
  return path.GetDirectoryName(codebase);
}

A nice helper method to include within an application is one which takes a name of a file (or subdirectory) which should be located within our application directory and returns a full path to that file.

string GetPathToApplicationFile(string filename)
{
  string path = GetApplicationPath();
  return Path.Combine(path, filename);
}

For example GetPathToApplicationFile(@”config\foo.txt”); would return a string similiar to “\Program Files\TestApp\config\foo.txt” where \Program Files\TestApp is the directory the application is currently installed in.

Sample Project

[Download DetectApplicationDirectory.zip - 11.8KB]

A small sample project is available for download. When the application is started it displays a Message box that displays the location of the executable. Notice that the application correctly determines if the CAB file has been installed on to a storage card or the main memory of the device. It will also cope with the application files manually being moved to a different location.

The CAB file also installs two text files within the application directory. By using the main menu you can load one of these files and display its contents within the window.

How to run an application immediately after installation

Thursday, November 15th, 2007

It is quite common for commercial software to have a registration or configuration process which must be completed immediately after installation in order for the software to become operational. This blog entry outlines one technique for getting such a process to automatically occur after installation of a Windows Mobile software package.

My solution is largely based upon a sample application provided with the Windows Mobile 5.0 and Windows Mobile 6 SDKs. If you haven’t found these samples yet (installed by default) I encourage you to investigate them further.

Solution Overview
Most Windows Mobile Software is installed via CAB files. A CAB file is an archive which installs a number of files and registry settings onto a PDA. A less commonly used feature of a CAB file is that of a setup dll. A setup dll (traditionally named setup.dll) is a DLL which can hook into various steps of the installation/uninstallation process in order to extend or modify the process. The process of using a setup dll is described within MSDN in an article titled “Optional Setup.dll Files for installation“.

When the device processes a CAB file that includes a setup dll, it extracts the DLL and calls specifically named functions within it at the following stages of the installation process:

Since the DLL must export a set of functions it typically must be implemented in a native language such as C or C++. The functions exported by the setup.dll can perform any task they want and can optionally decide to abort the installation process.

So in order to run an application after installation of a CAB file, one approach is to write a setup dll that implements an Install_Exit() function that launches the newly installed executable.

Launching an application on installation
Since we want to perform a custom action in response to the installation process completing the correct place to place our custom code is the Install_Exit entry point.

One of the parameters to this entry point (as described in MSDN) is pszInstallDir which contains the path to the location the user has decided to install the application in (i.e. typically \Storage Card\Program Files\xyz or \Program Files\xyz). This will help us locate the executable that has been installed.

We can start the desired application by using the CreateProcess API. If we fail to launch the application we can return codeINSTALL_EXIT_UNINSTALL which will cause the CAB installation process to rollback any changes made during installation and display an error message to the user.

My sample application launches an application after installation by placing the following code within the Install_Exit function:

// We are provided with the installation folder the 
// user has installed the application into. So append
// the name of the application we want to launch. 
PROCESS_INFORMATION pi;
TCHAR szPath[MAX_PATH]; 
_tcscpy(szPath, pszInstallDir); 
_tcscat(szPath, _T("\\")); 
_tcscat(szPath, _T("TestApplication.exe")); 
 
// Start the application, and don't wait for it to exit 
if (!CreateProcess(szPath, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, &pi)) 
{ 
  // Failed to launch executable so indicate an error
  // and cause wceload to rollback the installation
  cie = codeINSTALL_EXIT_UNINSTALL; 
}

You will notice that this code sample hardcodes the name of the executable to launch (TestApplication.exe). It does however cope with users deciding to install the application on to an SD Card etc.

Using Visual Studio Smart Device CAB projects
ce-setup-dll-selected.pngce-setup-dll.pngHaving developed your custom setup.dll implementation you must package it into the CAB file in a particular way to indicate to the installation process that the file should be treated specially.

If you are using the Smart Device CAB project type within Visual Studio this is a two step process.

The first step is to add the “Primary Output” of your setup.dll project into the application folder of your setup project (use the file system viewer). This ensures that your dll is archived as part of the CAB file.

The second step is to indicate to the CAB building process which dll within your CAB file should be treated as the special “setup.dll”. To indicate which dll you want to use as the setup.dll within Solution Explorer you should select your Smart Device CAB project, and then switch to the Property viewer. You will notice one of the CAB file properties is called “CE Setup DLL”. Using a popup dialog that appears when this property is selected you should be able to navigate to the DLL you included in the first step of the process.

If you are creating your CAB file via a manually written INF file you specify the DLL that should be used by specifying a CESetupDLL parameter in your [DefaultInstall] section (documented within MSDN) as shown below:

[DefaultInstall]
CopyFiles = CopyToInstallDir,CopyToWindows
CESetupDLL = MySetup.dll

Sample Application

[Download sample application - 19.3Kb]

I have produced a small sample application which demonstrates this technique. It consists of a solution (SetupDLL.sln) that contains the following projects.

  • TestApplication – An application (written in C#) to run after the installation process.
  • SetupDLL – The DLL the CAB installation process invokes during installation in order to execute TestApplication.
  • SetupDLLCab – The CAB file project that packages everything up into a single CAB file for the end user to install.

If you build the example CAB file and then install it on a device you should notice that at the end of the installation process (just before the “installation has completed” message box appears) the included .NET Compact Framework application will automatically run.

I will end this blog posting with a question. Is anyone interested in being able to write such setup dlls within a managed language such as VB.NET or C#, and if so what kind of custom behaviour/logic would you be interested in implementing?