Program.cs

builder.Services.AddSingleton<IBrowserHolder>(sp =>
{
    var holder = new BrowserHolder(sp)
    {
        CurrentUrl = sp.GetRequiredService<IConfiguration>()["openUrl"]
    };
    return holder;
});

   public interface IBrowserHolder
   {
       IWebDriver GetOrCreate();          // 每次登录按钮触发时调它
       string? CurrentUrl { get; set; }   // 需要打开的地址
   }
 public class BrowserHolder : IBrowserHolder, IDisposable
 {
     private readonly IServiceProvider _sp;
     private IWebDriver? _driver;
     private readonly object _lock = new();

     public string? CurrentUrl { get; set; }

     public BrowserHolder(IServiceProvider sp) => _sp = sp;

     public IWebDriver GetOrCreate()
     {
         lock (_lock)
         {
             // 如果窗口已关,则释放旧实例
             if (_driver != null && !_driver.IsAlive())
             {
                 _driver.Quit();
                 _driver.Dispose();
                 _driver = null;
             }

             if (_driver == null)
             {
                 _driver = BuildDriver();
                 if (!string.IsNullOrEmpty(CurrentUrl))
                     _driver.Navigate().GoToUrl(CurrentUrl);
             }
             else if (!string.IsNullOrEmpty(CurrentUrl))
             {
                 // 窗口还在,但想再跳一次同一地址(可选)
                 _driver.Navigate().GoToUrl(CurrentUrl);
             }

             return _driver;
         }
     }

     private IWebDriver BuildDriver()
     {
         var cfg = _sp.GetRequiredService<IConfiguration>();
         var logger = _sp.GetRequiredService<ILogger<BrowserHolder>>();

         var options = new ChromeOptions();
         options.PageLoadStrategy = PageLoadStrategy.None;
         // options.AddArgument("--headless=new");  //无头模式可在没有可视化桌面的时候开启
         options.AddArgument("--disable-gpu");
         options.AddArgument("--no-sandbox");
         options.AddArgument("--disable-dev-shm-usage");
         options.AddArgument("--disable-extensions");
         options.AddArgument("--disable-infobars");
         options.AddArgument("--window-size=1920,1080");
         options.AddArgument("--ignore-certificate-errors");
         options.AddArgument("--start-maximized");

         if (!string.IsNullOrEmpty(cfg["googleUrl"]))
             options.BinaryLocation = cfg["googleUrl"];

         var service = ChromeDriverService.CreateDefaultService(cfg["chromedriverUrl"], "chromedriver");
         service.Port = int.Parse(cfg["googlePort"]);
         service.EnableVerboseLogging = true;
         service.LogPath = "chromedriver.log";

         logger.LogInformation("正在启动 ChromeDriver …");

         if (!string.IsNullOrWhiteSpace(cfg["chromedriverUrl"]))
         {
             return new ChromeDriver(service, options);
         }
         else
         {
             return new ChromeDriver( options);
         }
         
     }

     public void Dispose()
     {
         _driver?.Quit();
         _driver?.Dispose();
     }

应用

 private readonly IBrowserHolder _browser;

public IndexModel(ILogger<IndexModel> logger, IBrowserHolder browser, IConfiguration configuration)
{
    _logger = logger;
    _browser = browser;
}


    public IActionResult OnPost()
    {
        try
        {

           
                var driver = _browser.GetOrCreate();
          
            return Page();
        }
        catch (Exception ex)
        {
           
            throw;
        }
      

     
    }
  //Windows  本地测试环境
  "googleUrl": "", // 空着程序会自己去找默认路径
  "chromedriverUrl": "", // 空着程序会自己去找默认路径
  "googlePort": 9520

具体模拟点击代码略。。。
以上代码在windows环境下安装了谷歌浏览器可直接运行

在Ubuntu环境中,需要做如下配置:


1.  net core 环境安装 (*)

wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y dotnet-runtime-6.0
sudo apt-get install -y dotnet-sdk-6.0

2.安装谷歌浏览器(*)

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
     sudo dpkg -i google-chrome-stable_current_amd64.deb || sudo apt -f -y install

   查看版本

google-chrome --version 

 下载对应版本的ChromeDriver

wget https://storage.googleapis.com/chrome-for-testing-public/142.0.7444.134/linux64/chromedriver-linux64.zip

解压并移动到系统路径:(路径需要在代码里面配置的)

 unzip chromedriver-linux64.zip
    sudo mv chromedriver-linux64/chromedriver /usr/local/bin/

赋予执行权限:(没有权限后面可能调用不了谷歌)

sudo chmod +x /usr/local/bin/chromedriver

3.将发布文件先用U盘拷贝到系统

 3.1 创建文件夹

sudo mkdir -p /var/www/myapp
sudo cp -r ~/var/www/myapp/* /var/www/myapp/

 3.2.把目录所有者改成你自己

sudo chown -R $USER:$USER /var/www/myapp

4.创建 systemd 服务文件(*)

sudo nano /etc/systemd/use/WebApplication1.service  -- WebApplication1自己换成其他的名称

  service配置内容

[Unit]
Description=My .NET Core Web App
After=network.target

[Service]
Environment=DISPLAY=:0
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/dotnet /var/www/myapp/WebApplication1.dll --urls "http://*:5000"
Restart=always
RestartSec=10
SyslogIdentifier=WebApplication1
Environment=ASPNETCORE_ENVIRONMENT=Production

[Install]
WantedBy=multi-user.target

Environment=DISPLAY=:0 是一定需要的,不然到时候打开不了浏览器

配置图形启动器

echo $DISPLAY          
export DISPLAY=:0

启动服务程序

systemctl --user daemon-reload
systemctl --user enable --now WebApplication1.service
loginctl enable-linger $USER   # 允许后台常驻(开机启动)

这里有一个大坑 千万不要用sudo 启动服务  如:

sudo systemctl daemon-reload
sudo systemctl enable WebApplication1
sudo systemctl start WebApplication1

如果用sudo会无法拿到配置Environment=DISPLAY=:0  导致无法打开浏览器

写入权限:(根据实际情况看是否需要)

sudo mkdir -p /var/www/myapp/logs
sudo chown www-data:www-data /var/www/myapp/logs
sudo chmod g+w /var/www/myapp/logs

5.添加use 对目录的权限(不添加程序无法运行)  (*)

sudo chown -R $USER:$USER /var/www/myapp
# 如果里面曾经 root 跑过日志、sqlite,一起改
sudo find /var/www/myapp -type f -exec chmod u+rw {} \;

6.设置固定IP (可选)

6.1.查看网卡名称


ip link show

6.2. 查看当前 enp1s0 的 IP 配置


ip addr show enp1s0

6.3. 查看当前网关


ip route show default

6.4.查看当前DNS


resolvectl status

6.5.输入配置(严格按照缩进)

/etc/netplan/01-netcfg.yaml


# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: NetworkManager
  ethernets:
    enp1s0:  # 你的网卡名称
      dhcp4: no
      addresses: [192.168.20.200/24]  # IP地址和子网掩码
      routes:
        - to: default
          via: 192.168.20.1          # 网关
      nameservers:
        addresses: [192.168.20.10]   # 你的 DNS 服务器
        search: [fbo.cn]             # DNS 搜索域

 

6.6.验证语法

sudo netplan generate

如果出现提示:

 WARNING **: 13:56:55.030: Permissions for /etc/netplan/01-network-manager-all.yaml are too open. Netplan configuration should NOT be accessible by others.

警告文件权限问题

修复:

sudo chmod 600 /etc/netplan/01-network-manager-all.yaml

6.7.应用配置

sudo netplan apply

6.8检查 IP 地址是否改变

ip addr show enp1s0

更多推荐