如何使用UWP Backburnd任务从本地存储(例如“C:\\”)读取文件?

如何使用UWP Backburnd任务从本地存储(例如“C:\\”)读取文件?,uwp,electron,Uwp,Electron,有没有办法从本地驱动器读取文件?比如C:\\eUWP\\UnReleasedFeatureTest.txt 我有一个后台任务,必须从文件中读取一些数据,路径是C:\\eUWP 下面是我的示例代码片段 [DataContract] public sealed class ConfigFileDetail { [DataMember] public string TestingUnreleasedFeatures { get; set; } } pub

有没有办法从本地驱动器读取文件?比如C:\\eUWP\\UnReleasedFeatureTest.txt 我有一个后台任务,必须从文件中读取一些数据,路径是C:\\eUWP

下面是我的示例代码片段

[DataContract]
public sealed class ConfigFileDetail
{
    [DataMember]
    public string TestingUnreleasedFeatures { get; set; }                
}
public void Run(IBackgroundTaskInstance taskInstance)
{
    string filepath = "C:\\eUWP\\UnReleasedFeatureTest.txt";
    string result = string.Empty;
    try
    {
        if (File.Exists(filepath)) { 
            using (StreamReader r = new StreamReader(new FileStream(filepath, FileMode.Open)))
            {
                var jsonData = r.ReadToEnd();
                DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(ConfigFileDetail));
                MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonData));
                stream.Position = 0;
                ConfigFileDetail dataContractDetail = (ConfigFileDetail)jsonSerializer.ReadObject(stream);
                ShowToast("Hi Praveer, I'm Electron's UWP sidekick" + dataContractDetail.TestingUnreleasedFeatures);
                UpdateTile("Hi Praveer see result, I'm Electron's UWP sidekick");
            }
        }
    }
    catch(Exception e)
    {
        Console.WriteLine("The error message is " + e.ToString());
    }
}
我也尝试过使用StorageFile,但不幸的是,它不起作用

Windows.Storage.StorageFolder storageFolder = 
   Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile = 
   await storageFolder.GetFileAsync("E:\\eUWP\\UnReleasedFeatureTest.txt");

有什么方法可以从后台任务从本地驱动器访问文件吗?

首先,您永远不能使用System.IO API访问硬盘驱动器上任意路径上的文件-由于安全原因,该API被阻止,因此UWP应用程序在思洛存储器中运行,并且不能破坏主机PC上的任何内容

但是,您可以通过StorageFile API使其工作,但首先需要在Package.appxmanifest文件中声明broadFileSystemAccess。在文本编辑器中打开它并更新根元素,如下所示:

<Package
  ...
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap mp rescap">
在元素中,您现在可以声明:

<rescap:Capability Name="broadFileSystemAccess" />
现在,建议使用StorageFile的第二个解决方案应该能够访问该文件,只要用户没有在设置中禁用文件系统访问


有关更多详细信息。

我看到您显示的代码中有一个缺陷

Windows.Storage.StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder; 
Windows.Storage.StorageFile sampleFile = await storageFolder.GetFileAsync("E:\\eUWP\\UnReleasedFeatureTest.txt");

您的StorageFolder来自当前的LocalFolder。将此设置为文件所在的文件夹。在这个例子中,看起来像E:\eUWP

这没有为我重新编程

我用应用程序触发器创建了一个后台任务,触发了它,并读取了文件。我使用的代码如下

测试后,可以根据需要随意安排代码。这只是一种方式。还要注意的是,这是概念证明,而不是产品代码,因为这是一个更广泛的主题。这里的目的是演示从后台访问文件

正如您所提到的,您需要broadfilesystemaccess功能,如下所述:。此外,您还需要用户手动允许文件系统访问。您需要在前台的主应用程序中检查是否有访问权限,如果尚未启用设置,则提示用户启用该设置。这将在本文档的“访问其他位置”部分的broadFileSystemAccess功能描述下讨论

来自App.xaml.cs

// NOTE: docs are here https://docs.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-an-inproc-background-task
protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
    base.OnBackgroundActivated(args);
    IBackgroundTaskInstance taskInstance = args.TaskInstance;
    await ReadText(taskInstance);
}

// NOTE: docs are here https://docs.microsoft.com/en-us/uwp/api/Windows.Storage 
// NOTE: sample is here https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/FileAccess
public static async Task ReadText(IBackgroundTaskInstance backgroundTaskInstance = null)
{
    // TODO: update the paths; these are the paths on my machine.
    string folderName = "D:\\out";
    string fileName = "helloworld.txt";
    var storageFolder = await StorageFolder.GetFolderFromPathAsync(folderName);
    var storageFile = await storageFolder.GetFileAsync(fileName);

    var E_NO_UNICODE_TRANSLATION = unchecked((int)0x80070459); 
    if (storageFile != null)
    {
        try
        {
            string fileContents = await FileIO.ReadTextAsync(storageFile);
            Debug.WriteLine($"The following text was read from '{storageFile.Name}':{Environment.NewLine}{fileContents}");
        }
        catch (FileNotFoundException ex)
        {
            Debug.WriteLine(ex.ToString());
        }
        catch (Exception ex) when (ex.HResult == E_NO_UNICODE_TRANSLATION)
        {
            Debug.WriteLine("Could not decode file to Unicode.");
        }
        catch (Exception ex)
        {
            // I/O errors are reported as exceptions.
            Debug.WriteLine($"Error reading from '{storageFile.Name}':{Environment.NewLine}{ex.ToString()}");
        }
    }
    else
    {
        Debug.WriteLine("File wasn't found");
    }
}
来自MainPage.xaml.cs

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    await TriggerBackgroundTask();
}

// NOTE: docs are here https://docs.microsoft.com/en-us/windows/uwp/launch-resume/trigger-background-task-from-app
ApplicationTrigger _AppTrigger;
private async Task TriggerBackgroundTask()
{
    _AppTrigger = new ApplicationTrigger();

    var requestStatus = await BackgroundExecutionManager.RequestAccessAsync();
    if (requestStatus != BackgroundAccessStatus.AlwaysAllowed)
    {
        string taskName = "Example application trigger";
        BackgroundTaskRegistration task = RegisterBackgroundTask(taskName, _AppTrigger);
        var result = await _AppTrigger.RequestAsync();
    }
}

// NOTE: docs are here https://docs.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-an-inproc-background-task
public static BackgroundTaskRegistration RegisterBackgroundTask(string taskName,
                                                                IBackgroundTrigger trigger,
                                                                string taskEntryPoint = null,
                                                                IBackgroundCondition condition = null)
{
    // Check for existing registrations of this background task.
    foreach (var cur in BackgroundTaskRegistration.AllTasks)
    {

        if (cur.Value.Name == taskName)
        {
            // The task is already registered.
            return (BackgroundTaskRegistration)(cur.Value);
        }
    }

    // Register the background task.
    var builder = new BackgroundTaskBuilder();
    builder.Name = taskName;
    builder.SetTrigger(trigger);

    if (!string.IsNullOrWhiteSpace(taskEntryPoint))
    {
        builder.TaskEntryPoint = taskEntryPoint;
    }

    if (condition != null)
    {

        builder.AddCondition(condition);
    }

    BackgroundTaskRegistration task = builder.Register();
    return task;
}

如果这不能为您解决问题,请共享一个最小化的示例以重现问题MCVE。

感谢您的回复。我更新了Package.appxmanifest文件。现在,我正在使用StorageFile,下面是我的代码。Windows.Storage.StorageFolder StorageFolder=Windows.Storage.ApplicationData.Current.LocalFolder;Windows.Storage.StorageFile sampleFile=等待storageFolder.GetFileAsyncE:\\eUWP\\UnReleasedFeatureTest.txt;错误:System.IO.FileNotFoundException:'文件名、目录名或卷标语法不正确。HRESULT异常:0x8007007B'它要求文件位于C:\Users\kumarpr\AppData\Local\Packages\8d0bb065-b69f-4da1-ba4c-fcd21d312da0_vp9fjm7zssgd8\LocalState`目录中。但是,我想从C:\\eUWP\`目录中读取。无论如何,我都可以做到这一点。E:\eUWP\中的文件真的存在吗?如果您声明broadFilesystemAccess功能,只要您拥有以用户身份访问该文件的权限,它就应该可以工作哦,我明白了!不要使用LocalFolder-这是LocalState目录。相反,直接使用GetFileFromPathAsync方法-@Martin Zikmund:谢谢您的回复。但是,不幸的是,GetFileFromPathAsync API也没有帮助我。StorageFile filepath=等待StorageFile.GetFileFromPathAsyncE:\eUWP\UnReleasedFeatureTest.txt;它一直在等待API的响应。事实上,在我的情况下,它挂在上面的代码。不,我们不能这样做,在我看来,我们无法访问任意路径。我问过很多人,但没有得到任何反馈。雪蒂,对不起。如果您试图访问不在指定文件夹中的文件,您将继续遇到这些错误。我不明白您的意思。您能给我看一下示例代码吗。我一路尝试,但都没有成功这里是我与一位专家的详细聊天,我得到异常抛出:“System.UnauthorizedAccessException”在System.Private.CoreLib.dll中我在git hub中有一个存储库