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

.NET MAUI应用前台接收共享文件触发Window已创建异常

.NET MAUI 处理跨应用共享文件时避免"Window was already created"异常

问题根源

你遇到的异常本质是:当应用已在前台运行时,处理共享意图的代码尝试重复创建新窗口,而MAUI不允许在已有活跃窗口的情况下重复调用OpenWindow创建主窗口。

解决方案:检测活跃窗口并复用已有实例

核心思路是在处理共享意图前,先判断应用是否已有活跃窗口,再决定是创建新窗口还是复用现有窗口并传递共享数据。

1. 通用检测逻辑

在处理共享数据的代码中,通过Application.Current.Windows集合判断窗口状态:

// 切换到UI线程执行(跨平台必须)
MainThread.BeginInvokeOnMainThread(() =>
{
    var sharedFiles = GetSharedFilesFromIntent(); // 替换为你的共享数据提取逻辑

    if (Application.Current.Windows.Count == 0)
    {
        // 应用未启动/无窗口,创建新窗口并传递数据
        var mainWindow = new MainWindow();
        Application.Current.OpenWindow(mainWindow);
        
        // 等待页面加载完成后传递数据
        mainWindow.PageLoaded += (s, e) =>
        {
            if (mainWindow.Page is MainPage mainPage)
            {
                mainPage.ProcessSharedFiles(sharedFiles);
            }
        };
    }
    else
    {
        // 应用已有窗口,激活并传递数据
        var activeWindow = Application.Current.Windows.FirstOrDefault(w => w.IsActive) 
                           ?? Application.Current.Windows[0];
        activeWindow.Activate();
        
        if (activeWindow.Page is MainPage mainPage)
        {
            mainPage.ProcessSharedFiles(sharedFiles);
        }
    }
});

2. 平台特定调整

Android平台(MainActivity.cs)

重写OnNewIntent方法处理共享意图:

protected override void OnNewIntent(Intent intent)
{
    base.OnNewIntent(intent);
    
    if (intent.Action is Intent.ActionSend or Intent.ActionSendMultiple)
    {
        var sharedFiles = ExtractSharedFilesFromIntent(intent); // 自定义方法提取文件路径
        HandleSharedIntent(sharedFiles);
    }
}

private void HandleSharedIntent(List<string> sharedFiles)
{
    MainThread.BeginInvokeOnMainThread(() =>
    {
        // 复用上述通用检测逻辑
        if (Application.Current.Windows.Count == 0)
        {
            var mainWindow = new MainWindow();
            Application.Current.OpenWindow(mainWindow);
            mainWindow.PageLoaded += (s, e) =>
            {
                if (mainWindow.Page is MainPage mainPage)
                {
                    mainPage.ProcessSharedFiles(sharedFiles);
                }
            };
        }
        else
        {
            var activeWindow = Application.Current.Windows.FirstOrDefault(w => w.IsActive) ?? Application.Current.Windows[0];
            activeWindow.Activate();
            if (activeWindow.Page is MainPage mainPage)
            {
                mainPage.ProcessSharedFiles(sharedFiles);
            }
        }
    });
}
iOS平台(AppDelegate.cs)

重写OpenUrl方法处理共享:

public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
    var sharedFiles = ExtractSharedFilesFromUrl(url); // 自定义方法提取文件路径
    MainThread.BeginInvokeOnMainThread(() =>
    {
        // 复用通用检测逻辑
        if (Application.Current.Windows.Count == 0)
        {
            var mainWindow = new MainWindow();
            Application.Current.OpenWindow(mainWindow);
            mainWindow.PageLoaded += (s, e) =>
            {
                if (mainWindow.Page is MainPage mainPage)
                {
                    mainPage.ProcessSharedFiles(sharedFiles);
                }
            };
        }
        else
        {
            var activeWindow = Application.Current.Windows.FirstOrDefault(w => w.IsActive) ?? Application.Current.Windows[0];
            activeWindow.Activate();
            if (activeWindow.Page is MainPage mainPage)
            {
                mainPage.ProcessSharedFiles(sharedFiles);
            }
        }
    });
    return base.OpenUrl(app, url, options);
}

3. 补充优化建议

  • 如果使用MVVM模式,建议通过IMessenger(如CommunityToolkit.Mvvm)发送共享数据消息,避免直接耦合页面和逻辑。
  • 确保ProcessSharedFiles方法支持重复调用,避免重复处理同一批文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:27:06