0

I've released several Windows Store apps over the last 2 years. And while they're moderately successful, they're all Productivity apps. And a Microsoft employee has confirmed (to me) that they do not allow "generic access to the DocumentsLibrary". What this means (in the context that we were speaking in), is that even if I held a Company account with the Windows Store, I/We are still not allowed to gain automatic access to files contained within the Documents Library and we are not allowed to Write data/files to the Documents Library - unless we also use SkyDrive - but if we use SkyDrive, we must also use the users SkyDrive Folder on the Desktop. And this really screws with how many apps should work.

I am finding it increasingly more difficult to release many apps that I have ideas for, due to such silly restrictions placed on us Developers.

Based on surveys and research, 92% of our customers do not like storing their data in the Cloud, and nor is it a part of how we want our apps to function. Our apps must function a certain way with and without Cloud storage.

Now, let's take a look at an all too common scenario of a normal, safe, Windows Desktop Productivity app. To keep the scenario simple, we'll be using a Notepad-like program. The only difference being, that it automatically loads all notes into the program on startup. And automatically determines if changes need to be saved, and saves them, if required.

In Windows 8 and 8.1. These apps are dead. We cannot access the Documents Library without a File Picker. What is the user going to do? Individually "pick"/select about 40 files using the Open File Picker? So that they can have them at hand in the app and just click it whenever they feel like modifying/viewing it? That's pathetic.

So I began using the AppData folder which they've told us in Documentation in the past is what that's there for.

But if the user Uninstalls the app, intentionally or unintentionally - their data, is lost. Gone. Unrecoverable.

(Please don't think this is a rant. It's not. I am merely explaining the problem in detail in case some don't quite understand my need for such access - or similar/same functionality).

So, my question is:

Since we cannot use the Documents Library for "generic use", where is a safe location to store files opened by, created and modified by, the user that is on their hard drive? A location that will still make it through App Certification. A location that will remain, even if the app gets uninstalled. A location where we have no-questions-asked access to read and/or write to/from - without the use of silly File Pickers.

0550
  • 132
  • 1
  • 12
  • 1
    I think you can have the user select a save folder, and then you can store them in the [Future Access List](http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.accesscache.storageapplicationpermissions.futureaccesslist). Might be what you're looking for. – Nate Diamond Feb 05 '14 at 16:16
  • @NateDiamond Thank you for this link. That page uses a FileOpenPicker as a sample. So what you're saying is, I can let them pick a folder (even the Documents folder?) and I will then have a list of all files in that folder that I can read from and write to without the use of any more File Pickers? – 0550 Feb 05 '14 at 16:23
  • 1
    I believe that is the case. You should be able to query the folder for files and access those files after they have given you access. I think there may be an additional popup when you try and add it to the future access list, but that is my understanding. Basically, a once-at-initialization thing. – Nate Diamond Feb 05 '14 at 16:25
  • Thanks fo your help @NateDiamond. I'll try that out right now. If you want to put that as an answer I'll stick around to accept if it works :) – 0550 Feb 05 '14 at 16:27
  • @NateDiamond Perfect. I will add my own answer with the working code that I just wrote. Thanks so much for your help, I really appreciate it. – 0550 Feb 05 '14 at 16:42

1 Answers1

3

Thanks to Nate's advice, I was able to write up a bit of code to get this working. Basically, I request permission to choose a folder and once the user has chosen their folder they want to work with, I then enumerate the files within, and add them to a ListView (a basic sample to test if it will work in my situation).

XAML:

<Page
    x:Class="test.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:test"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView ItemsSource="{Binding Note}" x:Name="list">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding name}" />
                </DataTemplate>
            </ListView.ItemTemplate>

        </ListView>
    </Grid>
</Page>

C#:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace test
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        ObservableCollection<Note> noteslist = new ObservableCollection<Note>();

        public class Note
        {
            public StorageFile file { get; set; }
            public string name { get; set; }
        }
        public MainPage()
        {
            this.InitializeComponent();
        }


        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            var opener = new Windows.Storage.Pickers.FolderPicker();
            opener.FileTypeFilter.Add(".txt");

            StorageFolder folder = await opener.PickSingleFolderAsync();

            if(folder != null)
            {
                StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);

                // Got it.
                IReadOnlyList<StorageFile> files = await folder.GetFilesAsync();

                if(files != null)
                {
                    foreach(StorageFile f in files)
                    {
                        noteslist.Add(new Note()
                            {
                                name = f.DisplayName,
                                file = f
                            });

                    }

                    list.ItemsSource = noteslist;
                }
            }
        }
    }
}

As this is just a simple test, there is basically zero error checking, but it's working for me.

0550
  • 132
  • 1
  • 12