.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
相关产品推荐
相关产品推荐

