You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Maui中<WindowsPackageType>None时FileSaver功能失效问题

问题描述

开发.NET Maui应用时,项目配置中设置了<WindowsPackageType>None</WindowsPackageType>,launchsettings.json配置如下:

{
"profiles": {
"Windows Machine": {
"commandName": "Project",
"nativeDebugging": false
}
}
}

使用CommunityToolkit.Maui.Storage.FileSaver的文件保存功能时出现报错,错误信息:

{FileSaverResult { FilePath = , Exception = System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL has been returned from a call to a COM component.
at CommunityToolkit.Maui.Storage.FileSaverImplementation.InternalSaveAsync(String initialPath, String fileName, Stream stream, CancellationToken cancellationToken) in //src/CommunityToolkit.Maui.Core/Essentials/FileSaver/FileSaverImplementation.windows.cs:line 31
at CommunityToolkit.Maui.Storage.FileSaverImplementation.InternalSaveAsync(String initialPath, String fileName, Stream stream, CancellationToken cancellationToken) in /
/src/CommunityToolkit.Maui.Core/Essentials/FileSaver/FileSaverImplementation.windows.cs:line 38
at CommunityToolkit.Maui.Storage.FileSaverImplementation.SaveAsync(String fileName, Stream stream, CancellationToken cancellationToken) in /_/src/CommunityToolkit.Maui.Core/Essentials/FileSaver/FileSaverImplementation.shared.cs:line 26, IsSuccessful = False }}

但打包为MSIX包运行时,FileSaver功能正常。

原因分析

当设置<WindowsPackageType>None</WindowsPackageType>时,应用以非打包桌面模式运行,而CommunityToolkit.Maui的FileSaver针对Windows平台的默认实现依赖打包环境的COM组件权限支持,非打包模式下无法正常调用相关组件,从而触发E_FAIL错误。

解决方法

方法1:切换调试配置为打包模式

修改launchsettings.json,将commandName改为MsixPackage:

{
"profiles": {
"Windows Machine": {
"commandName": "MsixPackage",
"nativeDebugging": false
}
}
}

同时将项目配置中的<WindowsPackageType>设为MSIX(或直接移除该配置,默认即为MSIX),调试时应用将以打包方式运行,FileSaver功能即可恢复正常。

方法2:自定义非打包模式下的文件保存逻辑

若需保持非打包模式运行,可针对Windows平台重写FileSaver实现,使用传统Win32文件对话框:

  1. 在项目的Windows平台目录下添加自定义实现类:
using CommunityToolkit.Maui.Storage;
using Microsoft.UI.Xaml;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using WinRT.Interop;
using Microsoft.Win32;

namespace YourAppNamespace.Windows;

public class CustomWindowsFileSaver : IFileSaver
{
    public async Task<FileSaverResult> SaveAsync(string fileName, Stream stream, CancellationToken cancellationToken)
    {
        return await SaveAsync(string.Empty, fileName, stream, cancellationToken);
    }

    public async Task<FileSaverResult> SaveAsync(string initialPath, string fileName, Stream stream, CancellationToken cancellationToken)
    {
        var saveFileDialog = new SaveFileDialog();
        saveFileDialog.FileName = fileName;
        
        // 获取当前窗口句柄
        var windowHandle = WindowNative.GetWindowHandle(Application.Current.Windows[0].Handler.PlatformView);
        var hwnd = new System.IntPtr(windowHandle);
        
        var dialogResult = saveFileDialog.ShowDialog(new WindowWrapper(hwnd));
        if (dialogResult == true)
        {
            try
            {
                using var fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create);
                await stream.CopyToAsync(fileStream, cancellationToken);
                return FileSaverResult.Success(saveFileDialog.FileName);
            }
            catch (Exception ex)
            {
                return FileSaverResult.Failure(ex);
            }
        }
        return FileSaverResult.Failure(new TaskCanceledException("用户取消了保存操作"));
    }

    // 辅助类用于传递窗口句柄
    private class WindowWrapper : System.Windows.IWin32Window
    {
        public WindowWrapper(IntPtr handle) => Handle = handle;
        public IntPtr Handle { get; }
    }
}
  1. 在MauiProgram.cs中注册自定义实现:
builder.Services.AddSingleton<IFileSaver>(sp =>
{
#if WINDOWS
    return new YourAppNamespace.Windows.CustomWindowsFileSaver();
#else
    return new CommunityToolkit.Maui.Storage.FileSaverImplementation();
#endif
});

此方案在非打包模式下会调用Win32原生文件对话框,绕开对打包环境COM组件的依赖,解决报错问题。

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 17:52:28