在使用 Selenium webdriver 的 Windows Server 虚拟机上将 Service Worker 作为服务运行还需要哪些其他先决条件?

问题描述 投票:0回答:2

我使用.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);
            }
        }
    }
}
c# selenium-webdriver windows-services
2个回答
1
投票

不确定这是不是问题,但

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)
        {
            // ...
        }
    });
}

0
投票

我通过仔细检查微软的文档https://learn.microsoft.com/en-us/dotnet/core/extensions/windows-service

来运行它

了解到我需要添加nuget包Microsoft.Extensions.Hosting.WindowsServices并在program.cs中添加以下内容

services.AddWindowsService(options =>
        {
            options.ServiceName = "ServiceName";
        });
© www.soinside.com 2019 - 2024. All rights reserved.