UWP Protect files embedding them

When developing apps you search for practical, tested and for real environments information. That is always my purpose, improve and go beyond in universal apps.

Let’s begin reading files in universal apps.

It is just two lines to read a file in your app and assign to an string, but might you do not know that you can go inside the folder of that app, navigate to the Assets folder and grab that file.

An UWP app should be a safe sandbox in both ways, one for the user to feel safe its Windows and on the other side for the developer, keeping the files safe.

In theory there is no limit about the size of the file to protect, can be any you consider, because the reader is asynchronous it can last how long it takes.

Text File

Suppose you have a json with few data, you prefer use json because it’s fast. If you place it at Assets/Data and the build options to Content, it will be available for any user at that path like C:\Program Files\WindowsApps\[AppName]_[Version]_[Platform]__[Id]

Content file

When you want to read or delete a text file with the build action as Content:

public static async Task<string> LoadContentTextFileAsync(string contenturi)
{
    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(contenturi));

    return await FileIO.ReadTextAsync(file);
}

public static async Task<bool> DeleteContentFile(string contenturi)
{
    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(contenturi));

    if (file != null)
    {
        await file.DeleteAsync(StorageDeleteOption.PermanentDelete);
        return true;
    }
    return false;
}

Now let’s change it to Embedded resource, and of course do not copy the file:

embedderesource

Take care, that if you have debugged the app before, you must uninstall it to make  disappear the file from Assets/Data.

The following methods makes really easy change from content to embedded resource.

public static Stream LoadEmbeddedStreamAsync(Type type, string contenturi)
{
    var assembly = type.GetTypeInfo().Assembly;
    var relativepath = ConvertContentEmbedded(contenturi);
    var embeddedpath = $"{type.Namespace}.{relativepath}";

    var stream = assembly.GetManifestResourceStream(embeddedpath);

    return stream;
}

public static async Task<string> LoadEmbeddedTextFileAsync(Type type, string contenturi)
{
    var stream = LoadEmbeddedStreamAsync(type, contenturi);

    return await ReadStringFromStreamAsync(stream);
}

What really means setting the file as embedded resource?

For one side we have added another entry to the resources.pri file (in case the file is in the project, in case is in a library it will be called [libraryname].pri.

To take a look to the file, just get the XML with the following VS tool:

pridecoder2

And not just open it and find the entry of the file:

resourceentry.JPG

Aside: If you install a UWP SDK like the 15003 prerelease, this and other tools are unique, that means that you won’t be able to upload an appx, because this tool ‘makepri’ is not a released version, you will have to uninstall both SDKs, and install again the latest released one.

If I understand it right, the file is embedded in the executable, so in theory is really protected, taking a look to it, we see the change in the size:

executables

We can check that easily adding an Image and setting it like a embedded resource:

addedimage

It is clear where the file is embedded now. Now we understand we should not add big files in here because it will make increase the executable and decrease time loading and performance.

But what about adding it inside a UWP library?

Big Files

In this case, I am going to add an image inside a assets library and try to show in a Image Control.

To make things easier, create a class in the UWP library called Library and the project AssetsLibrary and also let’s add a file inside Images:

assetslibrary

Now set the image as embedded resource and call it from the code behind of a page:

private async void Initialize()
{
    var stream = ResourceFilesService.LoadEmbeddedStreamAsync(typeof(Library),"ms-appx:///Images/spacebackground.jpg");

    var bitmapimage = new BitmapImage();

    BackgroundImage.Source = bitmapimage;

    await bitmapimage.SetSourceAsync(stream.AsRandomAccessStream());
}

Perfect the image is shown in the BackgroundImage control. So now you can implement behaviors or static methods for compiled binding to set the images you want to protect.

Big files to the local folder

Finally in case you need to copy a file from an embedded resource to the local folder, follow these steps:

public static async Task CopyResourceToLocal(Type type, string resourcepath, string filename)
{
    var localFolder = ApplicationData.Current.LocalFolder;
    var dbFile = await localFolder.TryGetItemAsync(filename) as StorageFile;

    if (null == dbFile)
    {
        var stream = LoadEmbeddedStreamAsync(type, resourcepath);

        //Copy the stream
        var storageFile = await localFolder.CreateFileAsync(filename);

        using (var outputStream = await storageFile.OpenStreamForWriteAsync())
        {
            await stream.CopyToAsync(outputStream);
        }
    }
}

For instance

 await ResourceFilesService.CopyResourceToLocal(typeof(Library),"ms-appx:///Data/Resource.txt","Local.txt");

And that’s all hope with this information, you can keep your app more robust avoiding possible user mistakes.

Download the ResourcesFileManager.cs

Take a look all I create about #UWP #Windows10 at @juanpaexpedite

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s