You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在C#控制台应用中创建无框浏览器窗口并实现交互与尺寸设置?

当然可以实现!在C#控制台应用里创建无框浏览器窗口、和主程序交互以及设置窗口尺寸都是完全可行的,下面我一步步给你讲清楚具体怎么做:

一、核心实现思路

控制台本身是纯文本环境,要创建带浏览器的UI窗口,我们需要借助.NET的WinForms框架加上微软官方的WebView2控件——这是目前最推荐的方案,兼容性好、功能完整,能轻松实现无框效果和双向交互。

首先你需要做两个准备:

  • 给控制台项目添加System.Windows.FormsSystem.Drawing的引用(右键项目→添加→引用→勾选这两个)
  • 通过NuGet安装Microsoft.Web.WebView2包(可以用Package Manager Console执行Install-Package Microsoft.Web.WebView2
二、创建无框浏览器窗口的完整代码示例

直接上可运行的代码,每一步我都加了注释:

using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.Web.WebView2.WinForms;

class Program
{
    static WebView2 _webView;
    static Form _browserForm;
    static Point _mouseDownLocation; // 用于无框窗口拖动

    static void Main(string[] args)
    {
        // 初始化WinForms的视觉样式和环境
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        // 创建无框窗口
        _browserForm = new Form
        {
            FormBorderStyle = FormBorderStyle.None, // 关键:去掉窗口边框
            Size = new Size(800, 600), // 设置初始窗口尺寸
            StartPosition = FormStartPosition.CenterScreen, // 居中显示
            BackColor = Color.White
        };

        // 给无框窗口添加拖动功能(可选,但很实用)
        _browserForm.MouseDown += (s, e) =>
        {
            if (e.Button == MouseButtons.Left)
            {
                _mouseDownLocation = e.Location;
            }
        };
        _browserForm.MouseMove += (s, e) =>
        {
            if (e.Button == MouseButtons.Left)
            {
                _browserForm.Location = new Point(
                    _browserForm.Location.X + e.X - _mouseDownLocation.X,
                    _browserForm.Location.Y + e.Y - _mouseDownLocation.Y);
            }
        };

        // 创建WebView2浏览器控件
        _webView = new WebView2
        {
            Dock = DockStyle.Fill, // 让浏览器填充整个窗口
            Source = new Uri("https://example.com") // 替换成你要加载的URL
        };

        // 等待WebView2初始化完成,设置交互桥接
        _webView.CoreWebView2InitializationCompleted += async (s, e) =>
        {
            // 注入一个供前端JS调用的对象,实现浏览器→控制台的消息传递
            _webView.CoreWebView2.AddHostObjectToScript("consoleBridge", new ConsoleMessageBridge());
            
            // 也可以提前注入一段JS,方便前端调用
            await _webView.ExecuteScriptAsync(@"
                window.sendToConsole = function(msg) {
                    window.chrome.webview.hostObjects.consoleBridge.ReceiveBrowserMessage(msg);
                };
            ");
        };

        // 将浏览器控件添加到窗口
        _browserForm.Controls.Add(_webView);

        // 启动窗口的消息循环(后台运行,不阻塞控制台输入)
        var uiThread = new System.Threading.Thread(() => Application.Run(_browserForm));
        uiThread.SetApartmentState(System.Threading.ApartmentState.STA);
        uiThread.Start();

        // 控制台交互逻辑:监听用户输入
        Console.WriteLine("控制台指令:");
        Console.WriteLine("- close:关闭浏览器窗口");
        Console.WriteLine("- sendmsg:给浏览器发送消息");
        Console.WriteLine("- resize [宽度] [高度]:调整窗口尺寸");
        Console.WriteLine("----------------------------------------");

        string input;
        do
        {
            input = Console.ReadLine()?.Trim().ToLower();
            switch (input)
            {
                case "close":
                    _browserForm.Invoke(new Action(() => _browserForm.Close()));
                    break;
                case "sendmsg":
                    _webView.Invoke(async () =>
                    {
                        await _webView.ExecuteScriptAsync("alert('来自控制台的消息:Hello Browser!')");
                    });
                    break;
                case var resizeCmd when resizeCmd?.StartsWith("resize") == true:
                    var parts = resizeCmd.Split(' ', StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length == 3 && int.TryParse(parts[1], out int width) && int.TryParse(parts[2], out int height))
                    {
                        _browserForm.Invoke(() => _browserForm.Size = new Size(width, height));
                        Console.WriteLine($"窗口已调整为:{width}×{height}");
                    }
                    else
                    {
                        Console.WriteLine("格式错误,请输入:resize 800 600");
                    }
                    break;
                default:
                    Console.WriteLine("未知指令,请重新输入");
                    break;
            }
        } while (input != "close");
    }
}

// 桥接类:必须标记为ComVisible,供WebView2的JS调用
[System.Runtime.InteropServices.ComVisible(true)]
public class ConsoleMessageBridge
{
    public void ReceiveBrowserMessage(string message)
    {
        Console.WriteLine($"【浏览器发来消息】:{message}");
    }
}
三、双向消息交互的具体实现

上面的代码已经包含了完整的双向交互逻辑,我再拆解一下:

1. 浏览器 → 控制台

通过AddHostObjectToScript方法将C#对象注入到前端JS环境,前端可以直接调用这个对象的方法传递消息。比如在前端页面里执行:

sendToConsole("我是浏览器页面的消息!");

控制台就会收到这条消息并打印。

2. 控制台 → 浏览器

控制台通过调用WebView2的ExecuteScriptAsync方法执行JS代码,实现给浏览器发送指令或消息。比如示例里的alert弹窗,你也可以调用前端自定义的函数,传递更复杂的数据。

注意点:

WinForms控件必须在UI线程操作,所以控制台的指令需要用Invoke方法切换到UI线程执行,避免跨线程异常。

四、窗口尺寸的设置

示例里已经实现了两种设置方式:

  1. 初始化时设置:创建Form对象时直接给Size属性赋值,比如new Size(1024, 768)
  2. 运行时动态调整:通过控制台指令resize [宽度] [高度]动态修改窗口尺寸,核心代码是_browserForm.Size = new Size(width, height),同样要注意在UI线程执行。
额外提示
  • 第一次运行WebView2需要下载对应的Runtime,如果不想让用户手动安装,可以通过NuGet安装Microsoft.Web.WebView2.Runtime.x86/x64/arm64包,把Runtime打包到项目里。
  • 无框窗口如果需要关闭按钮,可以自己在窗口里添加一个按钮控件,绑定Close事件。

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

火山引擎 最新活动