是否有人成功在C# Visual Studio VSIX扩展的ToolWindow中托管WebView2控件?
是否有人成功在C# Visual Studio VSIX扩展的ToolWindow中托管WebView2控件?
绝对可以!我自己和身边不少做VS扩展的同行都成功在WPF ToolWindow里替换掉老旧的WebBrowser,用上WebView2了——虽然微软的文档确实没专门针对VSIX场景做清晰指引,过程确实有点折腾,但完全可行。
分享一下亲测有效的步骤,帮你避开那些坑:
1. 先搭好基础环境
- 确保用的是Visual Studio 2022(VS2019对WebView2的集成支持不够完善,容易出问题)
- 在你的VSIX项目里安装
Microsoft.Web.WebView2NuGet包,选最新的稳定版就行,不用纠结太旧的版本
2. 修改ToolWindow的XAML
把原来的WebBrowser控件替换成WebView2,在你的ToolWindow对应的UserControl里这么写:
<UserControl x:Class="YourExtensionName.ToolWindows.YourWebViewToolWindowControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" Loaded="UserControl_Loaded"> <Grid> <wv2:WebView2 x:Name="MainWebView" /> </Grid> </UserControl>
3. 关键的初始化步骤(别在构造函数里搞!)
VSIX的运行环境和普通WPF App不一样,直接在构造函数初始化WebView2大概率会失败。一定要在UserControl的Loaded事件里异步初始化,而且要利用VS2022自带的WebView2运行时——完全不用让用户单独安装,这一点超省心:
using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.Wpf; using System.Windows; namespace YourExtensionName.ToolWindows { public partial class YourWebViewToolWindowControl : UserControl { public YourWebViewToolWindowControl() { InitializeComponent(); } private async void UserControl_Loaded(object sender, RoutedEventArgs e) { // 创建WebView2环境,用VS自带的运行时,不用单独部署 var webViewEnv = await CoreWebView2Environment.CreateAsync( browserExecutableFolder: null, // 自动用VS自带的运行时 userDataFolder: null, options: new CoreWebView2EnvironmentOptions { // 可以根据需求加配置,比如允许单点登录、调试模式等 AllowSingleSignOnUsingOSPrimaryAccount = true, EnableDeveloperTools = true }); // 确保CoreWebView2初始化完成 await MainWebView.EnsureCoreWebView2Async(webViewEnv); // 加载你的内容——不管是本地HTML字符串还是远程URL都可以 MainWebView.NavigateToString("<html><body><h1>WebView2在VSIX里跑起来了!</h1></body></html>"); // 要是加载远程地址就用:MainWebView.Source = new Uri("https://github.com"); } } }
4. 避开几个常见坑
- 别在构造函数里初始化WebView2:VS的ToolWindow加载时机特殊,构造阶段很多资源还没准备好,Loaded事件才是安全的时机
- 不用自己打包WebView2运行时:VS2022本身已经内置了,设置
browserExecutableFolder为null就能自动调用,省掉部署麻烦 - 如果要加载本地文件/资源:记得在CoreWebView2初始化后设置
MainWebView.CoreWebView2.Settings.AllowFileReadAccessFromFileUrls = true,不然会被安全策略拦截
我之前就是一开始在构造函数里初始化,折腾了半天没成功,后来改成Loaded事件异步处理就搞定了。现在用WebView2加载GitHub、本地HTML都完全正常,比老WebBrowser好用太多。
备注:内容来源于stack exchange,提问作者Yann Duran
相关产品推荐
相关产品推荐

