Question

I'm having a little difficulty figuring out what the cause of this error is. I've added FilePicker capabilities in the Manifest, and it's not like I'm trying to do anything crazy; just trying to save to a sub folder within the Documents folder...

Error: "An unhandled exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"

I have confirmed that my User Account is Admin and that it has Full Control over folders and files. But I'm not sure what else I can try.

public void NewBTN_Click(object sender, RoutedEventArgs e)
{

    var mbox = new MessageDialog("Would you like to save changes before creating a new Note?", "Note+ Confirmation");

    UICommand YesBTN = new UICommand("Yes", new UICommandInvokedHandler(OnYesBTN));
    UICommand NoBTN = new UICommand("No", new UICommandInvokedHandler(OnNoBTN));

    mbox.Commands.Add(YesBTN);
    mbox.Commands.Add(NoBTN);

    mbox.DefaultCommandIndex = 1;
    mbox.ShowAsync().Start();
}

async void OnYesBTN(object command)
{
    this.Dispatcher.Invoke(Windows.UI.Core.CoreDispatcherPriority.Normal, (s, a) =>
        {
            // User clicked yes. Show File picker.
            HasPickedFile = true;

        }, this, null);

    if (HasPickedFile)
    {
        FileSavePicker savePicker = new FileSavePicker();
        savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
        // Dropdown of file types the user can save the file as
        savePicker.FileTypeChoices.Add("Cascading Stylesheet", new List<string>() { ".css" });
        savePicker.FileTypeChoices.Add("Hypertext Markup Language", new List<string>() { ".html" });
        savePicker.FileTypeChoices.Add("Plain Text", new List<string>() { ".txt" });
        // Default extension if the user does not select a choice explicitly from the dropdown
        savePicker.DefaultFileExtension = ".txt";
        // Default file name if the user does not type one in or select a file to replace
        savePicker.SuggestedFileName = "New Note";
        StorageFile savedItem = await savePicker.PickSaveFileAsync();

        if (null != savedItem)
        {
            // Application now has read/write access to the saved file
            StorageFolder sFolder = await StorageFolder.GetFolderFromPathAsync(savedItem.Path);

            try
            {
                StorageFile sFile = await sFolder.GetFileAsync(savedItem.FileName);
                IRandomAccessStream writeStream = await sFile.OpenAsync(FileAccessMode.ReadWrite);

                IOutputStream oStream = writeStream.GetOutputStreamAt(0);
                DataWriter dWriter = new DataWriter(oStream);
                dWriter.WriteString(Note.Text);

                await dWriter.StoreAsync();
                oStream.FlushAsync().Start();

                // Should've successfully written to the file that Windows FileSavePicker had created.
            }
            catch
            {
                var mbox = new MessageDialog("This file does not exist.", "Note+ Confirmation");

                UICommand OkBTN = new UICommand("Ok", new UICommandInvokedHandler(OnOkBTN));

                mbox.Commands.Add(OkBTN);

                mbox.DefaultCommandIndex = 1;
                mbox.ShowAsync().Start();
            }
        }
    }
}

public void OnOkBTN(object command)
{
    this.Dispatcher.Invoke(Windows.UI.Core.CoreDispatcherPriority.Normal, (s, a) =>
        {
            // Do something here.
        }, this, null);
}
public void OnNoBTN(object command)
{
    this.Dispatcher.Invoke(Windows.UI.Core.CoreDispatcherPriority.Normal, (s, a) =>
        {
            // Don't save changes. Just create a new blank Note.
            Note.Text = String.Empty;
        }, this, null);
}

How can I write to a file that was created by the FileSavePicker?

Was it helpful?

Solution

You don't need to call StorageFolder.GetFolderFromPathAsync(savedItem.Path) and sFolder.GetFileAsync(savedItem.FileName). You must remove these two lines because they throw exception. You should use the StorageFile object which has been returned by method savePicker.PickSaveFileAsync(), because that object has all permissions. Then you can simply call savedItem.OpenAsync(FileAccessMode.ReadWrite).

OTHER TIPS

You probably do not have "Document Library Access" enabled in the capabilities portion of the appxmanifest of your app. Without this capability, windows will restrict access to the file system. There are similar capabilities for music, video, and picture libraries.

You have already added "File Picker" to the declarations portion, which is probably not what you want. The "File Picker" declaration indicates that if some other application invokes the file picker, your app will be listed as a possible source of files.

I've also found that adding Video or Picture Libraries access capability in Manifest only takes effect after restarting Windows 10. Maybe it is an issue with my computer, but I think it is worth to share.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top