在没有文件选择器的硬盘上读取和写入文件夹?

时间:2014-02-05 16:12:11

标签: c# .net xaml windows-runtime windows-store-apps

我在过去两年中发布了多个Windows应用商店应用。虽然它们取得了一定的成功,但它们都是生产力应用程序。一位微软员工已经确认(对我而言)他们不允许“对DocumentsLibrary的通用访问”。这意味着(在我们发言的上下文中),即使我在Windows商店中持有公司帐户,我/我们仍然不被允许自动访问文档库中包含的文件而我们不是允许将数据/文件写入文档库 - 除非我们也使用SkyDrive - 但如果我们使用SkyDrive,我们还必须使用桌面上的用户SkyDrive文件夹。这真的搞砸了应该有多少应用程序。

由于对开发人员施加了如此愚蠢的限制,我发现发布许多我有想法的应用程序变得越来越困难。

根据调查和研究,92%的客户喜欢将数据存储在云中,也不是我们希望应用程序运行的一部分。无论有无云存储,我们的应用都必须以某种方式运行。

现在,让我们来看一个普通,安全的Windows桌面生产力应用程序的常见情况。为了简化场景,我们将使用类似记事本的程序。唯一的区别是,它会在启动时自动将所有注释加载到程序中。并自动确定是否需要保存更改,并在需要时保存更改。

在Windows 8和8.1中。这些应用已经死了。没有文件选择器,我们无法访问文档库。用户要做什么?使用Open File Picker单独“选择”/选择大约40个文件?这样他们就可以在app中随身携带它们,只要他们想要修改/查看它就可以点击它?那太可悲了。

所以我开始使用AppData文件夹,他们在过去的文档中告诉我们这就是它的用途。

但是,如果用户有意或无意地卸载应用程序 - 他们的数据将丢失。不见了。不可恢复。

(请不要认为这是一个咆哮。它不是。我只是在详细解释问题,以防有些人不太了解我对此类访问的需求 - 或类似/相同的功能)。

所以,我的问题是:

由于我们无法将文档库用于“通用”,因此安全位置用于存储由其硬盘驱动器上的用户打开,创建和修改的文件?仍将通过App认证的位置。即使应用程序已卸载,也会保留的位置。在没有使用愚蠢的文件选择器的情况下,我们没有问题要求访问读取和/或写入的位置。

1 个答案:

答案 0 :(得分:3)

感谢Nate的建议,我能够编写一些代码来实现这一点。基本上,我请求权限选择一个文件夹,一旦用户选择了他们想要使用的文件夹,我就会枚举其中的文件,并将它们添加到ListView(一个基本样本,以测试它是否适用于我的情况)

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;
                }
            }
        }
    }
}

由于这只是一个简单的测试,基本上没有错误检查,但它对我有效。

相关问题