应用程序无法在 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);
嘿,我是 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);