应用程序无法在 Xamarin 中进一步处理磁盘/文件夹

App cannot further process disks / folder in Xamarin

嘿,我是 Xamarin 的新手,我希望你们能帮助我。由于 xamarin 中没有默认的文件夹选择器,我想自己实现它。问题是 UWP 以及 Android 抛出这个异常:

System.UnauthorizedAccessException HResult=0x80070005 Nachricht = 访问路径 'C:\Users\imtt\AppData\Local\Packagesef1aa30-7ffe-4ece-84c7-d2eaf1f8634b_wvdsmkc2tee92\LocalState\Test9.jpg' 被拒绝。 奎尔 = System.IO.FileSystem Stapelüberwachung: bei System.IO.FileSystem.DeleteFile(String fullPath) bei System.IO.File.Delete(字符串路径) bei MinimalReproducibleExample.ViewModel.DeleteFiles() 在 C:\Users\imtt\source\repos\MinimalReproducibleExample\MinimalReproducibleExample\MinimalReproducibleExample\ViewModel.cs: Zeile107 bei Xamarin.Forms.Command.<>c__DisplayClass4_0.<.ctor>b__0(对象o) bei Xamarin.Forms.Command.Execute(对象参数) bei Xamarin.Forms.ButtonElement.ElementClicked(VisualElement visualElement, IButtonElement ButtonElementManager) 北 Xamarin.Forms.Button.SendClicked() bei Xamarin.Forms.Platform.UWP.ButtonRenderer.OnButtonClick(对象发送者, RoutedEventArgs e)

这是xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="MinimalReproducibleExample.MainPage">
<StackLayout>
    <Button Text="Add Image" Command="{Binding AddImage}"/>
    <Button Text="Delete Images" Command="{Binding DeleteImages}"/>
    <Image Source="{Binding CreatedImage}"/>
</StackLayout>

这是隐藏代码:

using Xamarin.Forms;

namespace MinimalReproducibleExample
{
   public partial class MainPage : ContentPage
   {
      public MainPage()
      {
        BindingContext = new ViewModel();
        InitializeComponent();
      }
   }
 }
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Windows.Input;
    using Xamarin.Essentials;
    using Xamarin.Forms;

    namespace MinimalReproducibleExample
{
    public class ViewModel : INotifyPropertyChanged
    {

        private ImageSource image;
        private string fileFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Test");
        public ICommand AddImage { get; }
        public ICommand DeleteImages { get; }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string name = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        public ViewModel()
        {
            AddImage = new Command(ShowFilePicker);
            DeleteImages = new Command(DeleteFiles);
        }

        public ImageSource CreatedImage
        {
            get => image;
            set
            {
                image = value;
                OnPropertyChanged();
            }
        }


        public async void ShowFilePicker()
        {
            FilePickerFileType filePickerFileType = new FilePickerFileType(
                    new Dictionary<DevicePlatform, IEnumerable<string>> {
                        { DevicePlatform.iOS, new [] { "jpeg", "png", "mp3", "mpeg4Movie", "plaintext", "utf8PlainText", "html" } },
                        { DevicePlatform.Android, new [] { "image/jpeg", "image/png", "audio/mp3", "audio/mpeg", "video/mp4", "text/*", "text/html" } },
                        { DevicePlatform.UWP, new []{ "*.jpg", "*.jpeg", "*.png", "*.mp3", "*.mp4", "*.txt", "*.html" } }
                    });

            PickOptions pickOptions = new PickOptions
            {
                PickerTitle = "Wählen Sie eine oder mehrere Dateien aus",
                FileTypes = filePickerFileType,
            };

            IEnumerable<FileResult> pickedFiles = await FilePicker.PickMultipleAsync(pickOptions);
            List<FileResult> results = pickedFiles.ToList();

            if (results != null && results.Count > 0)
            {
                foreach (FileResult fileResult in results)
                {

                    using (Stream stream = await fileResult.OpenReadAsync())
                    {

                        DirectoryInfo directoryInfo = Directory.CreateDirectory(fileFolder);

                        string directoryPath = directoryInfo.FullName;

                        string filepath = Path.Combine(directoryPath, fileResult.FileName);

                        try
                        {

                            byte[] bArray = new byte[stream.Length];

                            using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate))
                            {
                                stream.Read(bArray, 0, (int)stream.Length);
                                int length = bArray.Length;
                                fs.Write(bArray, 0, length);
                            }

                            CreatedImage = ImageSource.FromFile(filepath);
                        }
                        catch (Exception exc)
                        {
                        }

                    }
                }
            }
        }

        public void DeleteFiles()
        {
            string[] filePaths = Directory.GetFiles(fileFolder);

            foreach(string filePath in filePaths)
            {
                File.Delete(filePath);
            }
        }
    }
}

我已经通过 windows 设置授予我的应用程序访问文件系统的权限,我还授予 Android 部分读写权限。我什至给了 UWP 部分“broadFileAccess”,甚至没有成功。

这与另一个问题有交叉,UWP部分可以将文件写入“Environment.SpecialFolder.LocalApplicationData”中的文件夹,但不允许删除该文件夹中的文件。

这是否与 UWP 和 Android 的沙箱有关?

App cannot further process disks / folder in Xamarin

我用你的代码测试过,问题是如果我们禁用 CreatedImage = ImageSource.FromFile(filepath); 这一行,当你删除它时文件正在被图像控制使用。它会按预期工作。

I need that image control to display the image

我们建议您使用流渲染图像,但不要直接从文件创建源。

例如

CreatedImage = ImageSource.FromStream(() => stream);