.NET7 Worker Service部署Windows服务遇Error1053及先决条件咨询
.NET 7 Worker Service 作为Windows服务启动报错Error 1053排查方案
问题描述
使用.NET 7开发Worker Service,本地通过dotnet build运行正常,但发布后作为Windows服务后台运行时,持续触发Error 1053(服务启动超时)。服务依赖Selenium WebDriver提取数据,服务器已安装最新版ChromeDriver与Chrome浏览器,问题仍未解决。疑问:
- 是否因服务器未识别驱动导致启动超时?
- 在Windows Server虚拟机上运行该服务,还需满足哪些先决条件?
使用的NuGet包
RUN dotnet add package Selenium.Support --version 4.8.1 RUN dotnet add package Azure.Storage.Blobs --version 12.15.1 RUN dotnet add package Microsoft.Azure.Functions.Extensions --version 1.1.0 RUN dotnet add package Microsoft.NET.Sdk.Functions --version 4.1.1 RUN dotnet add package Microsoft.VisualStudio.Azure.Containers.Tools.Targets --version 1.17.2 RUN dotnet add package System.Threading.AccessControl --version 7.0.1
其他安装项:
- 最新稳定版ChromeDriver
- Chrome浏览器
核心代码
using Azure.Storage.Blobs; using Screenshot_WorkerService.Interface; using Screenshot_WorkerService.Service; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; using OpenQA.Selenium; using OpenQA.Selenium.Support.Extensions; using System.Drawing; namespace Screenshot_WorkerService { public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; private readonly IBlobStorageServiceClient _blobServiceClient; public Worker(ILogger<Worker> logger, IBlobStorageServiceClient blobServiceClient) { _logger = logger; _blobServiceClient = blobServiceClient; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTime.Now); var timeout = 10; _logger.LogInformation("Reading urls values from blob"); var urlConfiguration = await _blobServiceClient.DownloadConfigrationBlob(); if (urlConfiguration.Urls is not null) { foreach (var item in urlConfiguration.Urls) { _logger.LogInformation("Preparing headless web browser"); var options = new ChromeOptions(); options.AddArguments(new List<string> { "--headless", "--hide-scrollbars" }); using var driver = new ChromeDriver(options); _logger.LogInformation("web browser complete"); driver.Manage().Window.Size = new Size(item.Width, item.Height); driver.Navigate().GoToUrl(item.Url); driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(timeout); try { _logger.LogInformation($"Searching class element: {timeout}"); var element = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout)).Until((d) => { d.Navigate().GoToUrl(item.Url); Thread.Sleep(5000); return d.FindElement(By.ClassName("v-menu")); }); var screenshot = driver.TakeScreenshot(); #if DEBUG screenshot.SaveAsFile($"{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.png"); #endif //Save to blobStorage _blobServiceClient.UploadImageToBlobAsync(screenshot); } catch (NoSuchElementException e) { // try Login _logger.LogInformation($"Exception: {e.Message}"); _logger.LogInformation($"Trying automate login"); var username = driver.FindElement(By.Id("input-12\"")); username.Clear(); username.SendKeys(""); var password = driver.FindElement(By.Id("input-13")); password.Clear(); password.SendKeys(""); var loginButton = driver.FindElement(By.XPath("//button[@class='v-btn v-btn--block v-btn--outlined theme--dark v-size--default primary--text']\r\n")); loginButton.Click(); driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(timeout); var screenshot = driver.TakeScreenshot(); #if DEBUG screenshot.SaveAsFile($"{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}.png"); #endif //Save to blobStorage _blobServiceClient.UploadImageToBlobAsync(screenshot); } catch (WebDriverTimeoutException e) { _logger.LogInformation($"Exception trying login was timed out: {e.Message}"); } catch (Exception e) { _logger.LogInformation($"Exception: {e.Message}"); } } } else { _logger.LogWarning("Reading returned no urls, check the blobstorage for url values"); } _logger.LogWarning("Done!"); await Task.Delay(TimeSpan.FromMinutes(20), stoppingToken); } } } }
问题排查与解决方案
1. 驱动识别是否导致启动超时?
是,大概率是驱动相关问题引发的启动超时,核心原因包括:
- Windows服务默认使用
Local System账户,该账户的环境变量、权限与本地测试账户不同,可能无法找到Chrome或ChromeDriver的路径。 - ChromeDriver未放入服务发布目录,或
Local System账户无访问驱动文件的权限。 - 无头模式参数不全,导致Chrome启动失败,阻塞服务初始化流程,超过30秒默认启动超时。
2. Windows Server运行的先决条件与修复步骤
(1)严格匹配Chrome与ChromeDriver版本
必须保证两者版本完全一致(小版本号也要对应),可通过chrome://version/查看Chrome版本,下载对应版本的ChromeDriver。
(2)调整服务运行账户与权限
- 避免使用
Local System账户,改用本地管理员账户运行服务,该账户拥有桌面交互权限(Selenium需要访问桌面会话)。 - 若坚持使用
Local System,需在服务属性中勾选「允许服务与桌面交互」(部分Windows Server版本可能受限)。 - 确保运行账户拥有以下权限:
- 访问Chrome安装目录(默认
C:\Program Files\Google\Chrome\Application\) - 访问ChromeDriver所在目录
- 访问Worker Service发布目录
- 访问Chrome安装目录(默认
(3)完善ChromeOptions配置
Windows服务环境下,仅--headless和--hide-scrollbars参数不足以启动Chrome,需补充以下关键参数:
var options = new ChromeOptions(); options.AddArguments(new List<string> { "--headless=new", // 新版无头模式,兼容性更好 "--hide-scrollbars", "--no-sandbox", // 禁用沙箱,服务环境必备 "--disable-gpu", // Windows下禁用GPU加速 "--disable-dev-shm-usage", // 解决容器/服务环境内存不足问题 "--start-maximized" // 确保窗口尺寸正确 }); // 手动指定Chrome路径,避免服务账户找不到 options.BinaryLocation = @"C:\Program Files\Google\Chrome\Application\chrome.exe";
(4)显式指定ChromeDriver路径
将ChromeDriver.exe放入服务发布目录,或在代码中显式指定驱动路径,同时隐藏命令行窗口:
// 指定驱动所在目录 var driverService = ChromeDriverService.CreateDefaultService(AppContext.BaseDirectory); // 隐藏ChromeDriver命令行窗口,服务环境更友好 driverService.HideCommandPromptWindow = true; using var driver = new ChromeDriver(driverService, options);
(5)延长服务启动超时时间
Windows服务默认启动超时为30秒,Selenium初始化可能需要更长时间,可通过注册表调整:
- 打开注册表编辑器,定位到
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control - 新建或修改
ServicesPipeTimeout(DWORD类型),设置值为60000(60秒)或更长 - 重启服务器使设置生效
(6)修复代码中的潜在问题
- 移除Thread.Sleep:
WebDriverWait的Until方法中使用Thread.Sleep(5000)会阻塞等待逻辑,应完全依赖WebDriverWait的超时机制。 - 异步方法添加await:
UploadImageToBlobAsync是异步方法,需添加await,否则会导致异步操作未完成就继续执行,引发资源泄漏或逻辑错误:await _blobServiceClient.UploadImageToBlobAsync(screenshot); - 修正元素定位错误:登录部分
By.Id("input-12\"")包含多余引号,应改为By.Id("input-12"),否则会引发NoSuchElementException,延长服务启动时间。
(7)日志与事件排查
- 配置文件日志(如Serilog),将详细日志输出到指定文件,便于排查服务启动时的错误。
- 查看Windows事件查看器的「应用程序日志」和「系统日志」,里面会记录服务启动失败的具体错误信息。
内容的提问来源于stack exchange,提问作者Ahune ajé o ahe
相关产品推荐
相关产品推荐

