我使用.NET 7开发了一个service worker,通过dotnet build测试成功运行。但是,当尝试发布代码并将其作为 Windows 服务在后台运行时,我始终会遇到错误 1053。我正在使用 Selenium webdriver 提取数据,并且在服务器上安装了最新的驱动程序和 Chrome。尽管如此,我仍然收到错误 1053 并在部署服务方面需要帮助。我不确定我错过了什么或我可能犯了什么错误。
会不会是服务器没有识别驱动,导致启动超时?
我使用的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
Other installations
Latest stabel chromedriver - https://sites.google.com/chromium.org/driver/
Chrome web browser```
代码可以在这里找到:https://pastebin.com/dAjhfK0i
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);
}
}
}
}
不确定这是不是问题,但
ExecuteAsync
应该尽快执行等待,以便尽快将执行控制权返回给调用者,当前实现将阻塞直到外循环的第一次迭代完成。尝试以下操作之一:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Yield();
while (!stoppingToken.IsCancellationRequested)
{
// ...
}
}
或
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Run(() =>
{
while (!stoppingToken.IsCancellationRequested)
{
// ...
}
});
}
我通过仔细检查微软的文档https://learn.microsoft.com/en-us/dotnet/core/extensions/windows-service
来运行它了解到我需要添加nuget包Microsoft.Extensions.Hosting.WindowsServices并在program.cs中添加以下内容
services.AddWindowsService(options =>
{
options.ServiceName = "ServiceName";
});