tauri在windows系统下动态创建webview卡主的问题 2025-03-28 02:21:10 最近在搞一个多标签页的应用,一个标签对应一个webview类似浏览器页签的形态,macos下开发测试都挺顺利,原以为搞完再windows下打包就可以了,果不其然有出意外了,还是那种全网又没有解决方案的~ ## 事情是这样的 使用rust代码将动态创建webview的逻辑封装为一个command给前端调用,前端通过调用这个command动态创建tab,核心逻辑是: ``` #[tauri::command] pub fn add_tab( state: State<'_, AppState>, tab_id: String, x: u32, y: u32, width: u32, height: u32, ) -> Result<(), Error> { let window = state.main_window.lock().unwrap(); let tab_view = window.add_child( tauri::webview::WebviewBuilder::new(&tab_id, WebviewUrl::App(PathBuf::from("index.html"))) .auto_resize(), LogicalPosition::new(x, y), LogicalSize::new(width, height), )?; let mut tabs = state.tabs.lock().unwrap(); tabs.push(tab_view); Ok(()) } ``` 代码在macos跑起来完全没问题,windows下运行表现则是卡主的状态,从devtools里看网络面板的ipc请求,发现一直没有返回,起初以为是ipc调用有问题,在代码里加了调试逻辑,发现调用是正常的,问题出在: ``` let tab_view = window.add_child( tauri::webview::WebviewBuilder::new(&tab_id, WebviewUrl::App(PathBuf::from("index.html"))) .auto_resize(), LogicalPosition::new(x, y), LogicalSize::new(width, height), )?; ``` 代码执行到这里就不动了,以我10多年前winform的开发经验判断,大概率是跟线程相关,毕竟windows的窗口处理机制和macos完全不是一回事。 ## 深入分析 看了下WebviewBuilder::new的内部实现逻辑,果然也是通过channel异步通信的机制处理的,在tauri的github里也找了类似的问题,有个哥们的回复提示了我: - <https://github.com/tauri-apps/tauri/issues/10010#issuecomment-2199339022> 虽然这哥们说比较忙,没时间处理,但也给了个思路,就是异步command的处理,看起来靠谱,于是有研究了下tauri的异步command有关文档: - <https://tauri.app/develop/calling-rust/#async-commands> 文档提到如果不是异步的command,代码是运行在主线程里,windows的主线程应该是跟窗口的主线程一起的,估计是这个原因导致卡主的,如果是异步command的话则运行在一个异步runtime中。 试着将`#[tauri::command]`调整为`#[tauri::command(async)]`,在测试果然还真可以。 非特殊说明,均为原创,原创文章,未经允许谢绝转载。 原始链接:tauri在windows系统下动态创建webview卡主的问题 赏 Next tauri在windows系统下构建msi包路径包含中文报错的问题