3
votes

I am in the process of updating my Windows Phone apps to use the new WP8 file storage APIs (LocalFolder) instead of WP7 APIs (IsolatedStorageFile).

Old Working Method

Here is how I successfully save the Image to the /Shared/ShellContent folder using the IsolatedStorageFile method (notice the /Shared/ShellContent/ prefix when saving the image, and also the isostore:/Shared/ShellContent/ prefix when updating the live tile.

using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
     if (myIsolatedStorage.FileExists("/Shared/ShellContent/LiveTileImagePath.jpg"))
     {
          myIsolatedStorage.DeleteFile("/Shared/ShellContent/LiveTileImagePath.jpg");
     }

     IsolatedStorageFileStream copyFileStream = myIsolatedStorage.CreateFile("/Shared/ShellContent/LiveTileImagePath.jpg");
     wb.SaveJpeg(copyFileStream, wb.PixelWidth, wb.PixelHeight, 0, 100);
     copyFileStream.Close();

     //UpdateTile
     ShellTile tile = ShellTile.ActiveTiles.First();

     if (tile != null)
     {
            FlipTileData tileData = new FlipTileData()
            {
                Title = "title",
                BackTitle = "backtitle",
                BackContent = "",
                WideBackContent = "",
                SmallBackgroundImage = new Uri("/Images/SmallIconBW.png", UriKind.RelativeOrAbsolute),
                BackgroundImage = new Uri("/Images/MediumKiss336.png", UriKind.RelativeOrAbsolute),
                BackBackgroundImage = new Uri("isostore:/Shared/ShellContent/LiveTileImagePath.jpg", UriKind.RelativeOrAbsolute),
                WideBackgroundImage = new Uri("/Images/MediumKiss336.png", UriKind.RelativeOrAbsolute),
                WideBackBackgroundImage = new Uri("isostore:/Shared/ShellContent/LiveTileImagePath.jpg", UriKind.RelativeOrAbsolute)
                };

                tile.Update(tileData);
            }
}

Problem To Be Solved

The problem arises when I use the new method to save the image. I can't seem to find the right image path to update the tile with. Here is my new method to save the image (NOTE: fileStream is a MemoryStream containing the jpeg image that I generate from a WriteableBitmap earlier in the method. It saves fine to storage for use in the app, but not to the Shared folder)

StorageFile liveTileImageFile = await localFolder.CreateFileAsync("/Shared/ShellContent/LiveTileImagePath.jpg", CreationCollisionOption.ReplaceExisting);

fileStream.Seek(0, SeekOrigin.Begin);

using(Stream sharedFolderStream = await liveTileImageFile.OpenStreamForWriteAsync())
{
    await fileStream.CopyToAsync(sharedFolderStream);
}

ShellTile tile = ShellTile.ActiveTiles.First();

if (tile != null)
{
    FlipTileData tileData = new FlipTileData()
    {
        Title = "Kiss Dictionary",
        BackTitle = "name",
        BackContent = "",
        WideBackContent = "",
        SmallBackgroundImage = new Uri("/Images/SmallIconBW.png", UriKind.RelativeOrAbsolute),
        BackgroundImage = new Uri("/Images/MediumKiss336.png", UriKind.RelativeOrAbsolute),
        BackBackgroundImage = new Uri("isostore:/Shared/ShellContent/LiveTileImagePath.jpg", UriKind.RelativeOrAbsolute),
            WideBackgroundImage = new Uri("/Images/MediumKiss336.png", UriKind.RelativeOrAbsolute),
            WideBackBackgroundImage = new Uri("isostore:/Shared/ShellContent/LiveTileImagePath.jpg", UriKind.RelativeOrAbsolute)
         };

         tile.Update(tileData);
}

The problem is that I can not save the image to the Shared/ShellFolder, I get this exception message:

The filename, directory name, or volume label syntax is incorrect. (Exception from HRESULT: 0x8007007B)

If you have updated your app's LiveTile updating, please explain the path you used to save and the file path you assigned to your LiveTile images.

UPDATE:

Rob's answer below fixes the exception and allows me to save to the folder. I made an alteration to the file path used on my tile update (thanks to Scott Lovegrove's suggestion):

Instead of the old way:

BackBackgroundImage = new Uri("isostore:/Shared/ShellContent/LiveTileImagePath.jpg", UriKind.RelativeOrAbsolute)

I used this successfully

BackBackgroundImage = new Uri("isostore:shared\\shellcontent\\LiveTileImagePath.jpg", UriKind.RelativeOrAbsolute)
1
Just so we are clear you're saying its blowing up on the CreatFileAsync line?\Anthony Russell
Yes, the problem was that it would not recursively get the folder. Rob's answer below fixes that issue by getting each folder by itself, then creating the file in the last folder.Lance McCarthy

1 Answers

4
votes

This is ugly but it works... you need to drill down into each directory of isolated storage. You can't just put in the full path (that would be too easy).

So instead of:

StorageFile liveTileImageFile = await localFolder.CreateFileAsync("/Shared/ShellContent/LiveTileImagePath.jpg", CreationCollisionOption.ReplaceExisting);

You should have:

var sharedFolder = await localFolder.GetFolderAsync("Shared");
var shellContentFolder = await sharedFolder.GetFolderAsync("ShellContent");
var liveTileImageFile = await shellContentFolder.CreateFileAsync("LiveTileImagePath.jpg", CreationCollisionOption.ReplaceExisting);

Hope that helps.