Windows Forms程序锁屏状态下捕获浏览器截图的实现方案求助
锁屏状态下Windows任务计划执行浏览器截图的解决方案
我用Windows Forms开发了一款程序,用来控制浏览器并定期截图,目的是检查不同时段的浏览器状态。现在要求这个程序能在锁屏的Windows系统里通过任务计划程序运行,其他问题都解决了,唯独浏览器截图搞不定。
尝试过的方案及问题
1. Selenium + ChromeDriver
使用的代码:
new DriverManager().SetUpDriver(new ChromeConfig()); var options = new ChromeOptions(); options.AddArgument("--disable-gpu"); options.AddArgument("disable-software-rasterizer"); var driver = new ChromeDriver(options); driver.Navigate().GoToUrl(url); // 捕获网页截图 Screenshot screenshot = ((ITakesScreenshot)driver).GetScreenshot(); // 转换为Bitmap Bitmap bmp = new Bitmap(new MemoryStream(screenshot.AsByteArray));
问题:锁屏状态下要么浏览器启动失败,要么无法完成截图。尝试添加--headless参数时遇到CORS限制。
2. PuppeteerSharp
问题:遇到DRM限制(公司内部合法使用)。
3. 屏幕拷贝方法
使用的代码:
Bitmap screenshot = new Bitmap(s.Bounds.Width, s.Bounds.Height, PixelFormat.Format32bppRgb); for (int i = 0; i < 2; i++) { using (Graphics memoryGraphics = Graphics.FromImage(screenshot)) { memoryGraphics.CopyFromScreen(s.Bounds.X, s.Bounds.Y, 0, 0, s.Bounds.Size, CopyPixelOperation.SourceCopy); return screenshot; } }
问题:锁屏状态下系统不存在Screen对象,此方法无效。
可行解决方案建议
方案一:调整ChromeDriver参数+任务计划配置
给ChromeOptions添加以下参数,适配锁屏环境并规避CORS问题:
options.AddArgument("--no-sandbox"); options.AddArgument("--disable-dev-shm-usage"); options.AddArgument("--remote-debugging-port=9222"); // 使用新版headless模式,避免旧版的CORS兼容性问题 options.AddArgument("--headless=new");
同时在任务计划程序中配置:
- 勾选**"不管用户是否登录都要运行"**
- 选择具有管理员权限的账户运行任务
- 在"设置"选项卡中取消勾选**"如果计算机改用电池电源,则停止任务"**
方案二:通过Windows API创建虚拟桌面
锁屏时系统会切换到无交互会话,可通过Windows API创建虚拟桌面,在独立桌面环境中运行浏览器并截图:
using System.Runtime.InteropServices; [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags, uint dwDesiredAccess, IntPtr lpsa); [DllImport("user32.dll", SetLastError = true)] public static extern bool SetThreadDesktop(IntPtr hDesktop); [DllImport("user32.dll", SetLastError = true)] public static extern bool CloseDesktop(IntPtr hDesktop); [DllImport("kernel32.dll")] public static extern uint GetCurrentThreadId(); [DllImport("user32.dll")] public static extern IntPtr GetThreadDesktop(uint dwThreadId); // 创建虚拟桌面 IntPtr virtualDesktop = CreateDesktop("ScreenshotDesktop", IntPtr.Zero, IntPtr.Zero, 0, 0x000F0000, IntPtr.Zero); if (virtualDesktop != IntPtr.Zero) { // 切换到虚拟桌面 if (SetThreadDesktop(virtualDesktop)) { // 在此执行浏览器启动、导航、截图操作 // ... } // 切换回原桌面 SetThreadDesktop(GetThreadDesktop(GetCurrentThreadId())); // 销毁虚拟桌面 CloseDesktop(virtualDesktop); }
注意:程序需以管理员权限运行,任务计划中要配置对应权限。
方案三:调整PuppeteerSharp参数规避DRM限制
针对DRM保护页面,添加相关参数启用DRM支持并调整安全策略:
var browserFetcher = new BrowserFetcher(); await browserFetcher.DownloadAsync(); var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true, Args = new[] { "--no-sandbox", "--disable-dev-shm-usage", "--enable-widevine-cdm", "--disable-features=IsolateOrigins,site-per-process" } });
注意:--disable-features=IsolateOrigins,site-per-process会放宽隔离策略,仅在内部可信环境中使用。
内容的提问来源于stack exchange,提问作者Valter Rönisch
相关产品推荐
相关产品推荐

