Category: Uncategorized

Windows Phone 7 : Code Snippet: Enumerate Files in Isolated Storage

This sample code uses the IsolatedStorageFile class to create a few test directories and populates them with files.  Then it recursively enumerates the files and directories, displaying the output in the debug window.

  1. public void EnumerateIsolatedStorageFiles()
  2. {
  3.     try
  4.     {
  5.         // Get an isolated store for this applicaiton and put it into an
  6.         // IsolatedStorageFile object.
  7.  
  8.         using (IsolatedStorageFile isoStore =
  9.             IsolatedStorageFile.GetUserStoreForApplication())
  10.         {
  11.             // Create sub directories and create files
  12.             // in them to test enumeration
  13.             isoStore.CreateDirectory("A");
  14.             IsolatedStorageFileStream streamA =
  15.                 new IsolatedStorageFileStream(@"A\TestFileA.Txt", FileMode.Create, isoStore);
  16.  
  17.             isoStore.CreateDirectory("B");
  18.             IsolatedStorageFileStream streamB =
  19.                 new IsolatedStorageFileStream(@"B\TestFileB.Txt", FileMode.Create, isoStore);
  20.  
  21.             isoStore.CreateDirectory("C");
  22.             IsolatedStorageFileStream streamC =
  23.                 new IsolatedStorageFileStream(@"C\TestFileC.Txt", FileMode.Create, isoStore);
  24.  
  25.             isoStore.CreateDirectory(@"C\1");
  26.             IsolatedStorageFileStream streamC1 =
  27.                 new IsolatedStorageFileStream(@"C\1\TestFileC1.Txt", FileMode.Create, isoStore);
  28.  
  29.             isoStore.CreateDirectory(@"D\1\2\3\4\5");
  30.             IsolatedStorageFileStream streamD =
  31.                 new IsolatedStorageFileStream(@"D\1\2\3\4\5\TestFileD.Txt", FileMode.Create, isoStore);
  32.  
  33.             streamA.Close();
  34.             streamB.Close();
  35.             streamC.Close();
  36.             streamC1.Close();
  37.             streamD.Close();
  38.  
  39.             // There might be a small delay between when the above code
  40.             // executes and when the files are created in the store.
  41.             // Closing and opening the store in this example ensures that
  42.             // the common language runtime has finished creating the files.
  43.         } // using
  44.  
  45.         using (IsolatedStorageFile isoStore =
  46.             IsolatedStorageFile.GetUserStoreForApplication())
  47.         {
  48.             // List files in root
  49.             foreach (string file in isoStore.GetFileNames())
  50.             {
  51.                 Debug.WriteLine(file);
  52.             }
  53.             // Recursively enumerate sub-directories and list contents
  54.             GetFiles(isoStore, @"\");
  55.         } // using
  56.     }
  57.     catch (IsolatedStorageException e)
  58.     {
  59.         Debug.WriteLine(e.Message);
  60.     }
  61. }
  62.  
  63. // Recursively enumerate sub-directories
  64. void GetFiles(IsolatedStorageFile isoStore, string directory)
  65. {
  66.     string[] DirNames;
  67.     if (directory == @"\")
  68.         DirNames = isoStore.GetDirectoryNames();
  69.     else
  70.         DirNames = isoStore.GetDirectoryNames(directory + @"\*");
  71.  
  72.     foreach (string dir in DirNames)
  73.     {
  74.         string mDir =
  75.             directory == @"\" ? directory + dir : directory + @"\" + dir;
  76.         foreach (string file in isoStore.GetFileNames(mDir + @"\*.*"))
  77.         {
  78.             Debug.WriteLine(file);
  79.         }
  80.         GetFiles(isoStore, mDir);
  81.     }
  82. }

 

Enjoy!

Mike

This work is licensed under a Creative Commons license.

Bing for mobile – Voice Turn-by-Turn Directions – New and Improved UI!

Bing Mobile 6.1

 

 

One of my favorite Windows Mobile applications has been Bing (the application formerly known as “Live Search”).  This application has saved my bacon on more than one occasion when travelling on business or vacation. The ability to search for vital resources, wherever I am, like the closest Starbucks has been invaluable to me.

While Live Search was great, the UI was a little clunky and was not developed with capacitive screens and the corresponding touch navigation in-mind. Capacitive screens while more sensitive to touch, have a larger minimum hit target size. Actually comparing Live Search to the new Bing is a good example of how an application designed for a resistive screen has been updated to also work with capacitive screens.

 

The usability has greatly improved. For example to starting navigating to the nearest Starbucks, you:

 

  • From the Bing home page, Tap ‘Speak’ and say ‘Starbucks’

Bing for mobile, like on the desktop, daily updates the cool photo used on the home page background.

  • Select the ‘Starbucks’ you want to go to

Select the appropriate tab to search the web of do a web local search of your search term.

  • Tap the Car icon for driving directions

Note the detail information here including phone number, address, rating, map thumbnail, etc.

  • Tap on ‘Navigate’ (If you are on foot, select the ‘Walk’ tab for walking directions.)

Single click on 'Navigate' to start with voice directions from your current location

Immediately a route is calculated for you and Silicon Sally is telling you where to go. Yes ‘telling you’, with voice directions! This is a huge improvement over Live Search that had text only turn-by-turn directions. In the Bing settings, you can specify if you want to route via the shortest or fastest route. You can also configure Bing to consider real-time traffic conditions when calculating your route. 

By default, you will see traffic conditions on map

Now featuring ‘auto-rerouting’! Live Search would prompt you will a demoralizing ‘Are you lost? Would you like to reroute from here?’ prompt whenever you deviated from your planned route. Bing for mobile smartly just tells you that it is ‘rerouting’ and updates your driving directions based on your current location.

All the great features of Live Search are still here like quick access to locally playing movies and show times.

You can install Bing for mobile from the Marketplace for Windows Phone here.

More information here.

Enjoy!

Mike

Install SQL Server Compact using the MultiCAB pattern

Update: I’ve updated the sample to be independent of the ‘\Program Files’ string. Also, the sample now supports installing onto a Storage Card.

A popular sample for demonstrating how to install application dependencies via embedded CAB files is MultiCAB Install. With this pattern you can distribute dependant cab files via a single container CAB. “Can apps be distributed via Windows Marketplace for Mobile using this?”,you ask. Yes they can.

Installing SQL Server Compact dependencies is a good fit for this pattern. I have updated the sample here customized to distribute the latest SQL Server Compact for Windows Mobile devices.

The sample checks if SQL Server Compact 3.5 is installed (See IsSQLCEUpdateRequired() in mcsetup.cpp) and if not, launches the multicab EXE which installs each dependant cab in sequence. (See the multicab whitepaper included in the sample for an in-depth explanation of how it works.)

How does the sample check to see if v3.5 is installed? It checks the registry for the following entry:

  1. \Software\Microsoft\Microsoft SQL Server Compact Edition\v3.5

This this exists, then installation of the SQLCE cabs is skipped. Note that this registry key only exists if SQLCE has been installed via a CAB file. That is, this registry key does not exist of SQLCE is in ROM. As of this writing, 3.5 (SP1 or SP2) is not distributed in ROM. See here for a list of OS and corresponding SQLCE versions: Description of the various build versions of SQL Server Compact Edition.

The sample does not do version checking on the binaries. Therefore it does not detect if you are upgrading from SQLCE 3.5 SP1 to SP2. The way it is written now, it will not update the binaries to SP2. This sample does address the popular scenario of updating an ‘off the shelf’ device with the latest version of SQL Server Compact.

More SQL Server Compact Links: Mike

This work is licensed under a Creative Commons license.

Windows Marketplace for Mobile – Certification Testing Tips

Lately I’ve been spending a portion of my time supporting developers over in the Windows Marketplace for Mobile forum. I’ve collected some of the common issues folks are having and posted them over on the Windows Mobile Developer blog here. In this post, I go over tips to help you pass certification testing, specifically on running Hopper and supporting multiple screens. Check it out!

Enjoy!

Mike

How to make changes to CAB file – without an .INF file

I was developing a few themes for Standard and Professional devices (using the Windows Phone Custom Theme Generator tool to get me started) and found that when installing the CAB on Standard devices, I would get the following error:

The program you have installed may not display properly because it was designed for a previous version of Windows Mobile software.

Normally to fix this error, you would edit the .INF file and add BuildMax=0xE0000000 to the CEDevice section as follows (See here for explanation of BuildMax):

[CEDevice]
VersionMin = 3.0
VersionMax = 100.0
BuildMax=0xE0000000

In this case, I did not have an .INF file since the CAB was generated by the Theme Generator. Doing a Bing search, I found a great tool (Benoit Thonnart’s MSCEInf) that helps with the process of creating a .INF file from a CAB file and extracting files from the CAB with the true filenames. Using this tool, I created the .INF file, edited it, and then recreated the CAB file using the .INF file and CABWIZ.EXE. MSCEinf’s feature of extracting the true filename saves a lot of time, saving you the drudgery of renaming the files, as specified in the _setup.xml file, by hand.  (When CABWIZ creates the CAB, it converts the filenames to 8.3 names).

Step-by-Step guide:

  • Create dedicated destination directory.
  • Copy MSCEInfEn to this directory.
  • Create .INF file. 
    • Start MSCEInfEn.EXE
      • Open the CAB file
      • Click on the icon in upper left, ‘Save INF File rebuilt’ to save .INF file.
  • Extract files from CAB, using the true filenames
    • Using MSCEInfEn,  turn Off ‘Use Folders’
      • Click 5th button from left ‘Extract Filenames’ (should see icon with red X through it).
    • Using MSCEInfEn,  extract files
      • Click 4th button from left ‘Extract CAB files with original names in a folder’.
      • Click ‘Extract’ and select the destination directory.
  • At this point you should have the files of your theme / application and the .INF file in the destination directory.
  • Modify .INF file
    • Open .INF file saved in Step 1 and add the following line below [CEStrings]
      • [CEDevice]
        BuildMax=0xE0000000
    • Save .INF file
  • Rebuild CAB file.
    • Start a Command Line. (Start | Run | cmd)
    • Change to the destination directory.
    • Using CABWIZ.EXE recreate the cab file with the following command:
      • Cabwiz <filename>.inf
      • You may see a warning regarding AddReg, this can be ignored.
  • Test the CAB file.

Thanks,

Mike

Windows Mobile: Problem with Message Interception failing

I’ve had a couple of clients that ran into a problem where their SMS Message interceptor would fail to fire. (For an introduction to this pretty cool technology see here.) This was a hard to track down problem, because the interceptor would work on some devices, and the emulator, but not on a handful of devices. Because this worked on several devices, it seemed the code was without errors.

We resolved this by determining if any of the existing SMS interceptors were interfering with this one. SMS Interceptors fire in a chain with each one handing off to the next. That is they should hand-off. If you are implementing a native code interceptor using IMailRuleClient, you can stop the message processing by setting the handled flag to MRC_HANDLED_DONTCONTINUE. This prevents any further processing of the message. However, this flag should ONLY be used if the message you are receiving is private to your application / interceptor. If other interceptors could possibly process the message, you should set the handled flag to MRC_HANDLED_CONTINUE or MRC_NOTHANDLED. For managed code, if you would like the message to be available to other interceptor applications, create the MessageInterceptor instance passing the InterceptionAction.Notify enumeration value to the MessageInterceptor constructor.

You can test for interfering interceptors by going to [HKEY_LOCAL_MACHINE\Software\Microsoft\Inbox\Svc\SMS\Rules] and set each rule to ‘0’ until the problem goes away. The last rule you change to ‘0’ before the problem goes away will be the problematic rule. Note that you need to soft reset the device after changing the registry key.

For example:

[HKEY_LOCAL_MACHINE\Software\Microsoft\Inbox\Svc\SMS\Rules]

"{27E9801F-330B-4c6a-A7BF-A670D8C53C5D}"=dword:00000001

"{E85FD9C3-4F5E-4c75-8C21-0F850274DEF5}"=dword:00000001 <- Change to 0 to test

Once you have located the problematic rule, you can get more information on it (for example, the DLL name) by searching for the GUID underneath HKEY_CLASSES_ROOT\CLSID.

 

Thanks,

Mike