private static async Task <RevisionInfo> DownloadChromiumAsync(BrowserFetcherOptions options) { var fetcher = Puppeteer.CreateBrowserFetcher(options); if (fetcher.LocalRevisions().Contains(BrowserFetcher.DefaultRevision)) { return(fetcher.RevisionInfo(BrowserFetcher.DefaultRevision)); } try { Logger?.Debug($"Downloading Chromium r{BrowserFetcher.DefaultRevision}..."); var revisionInfo = await fetcher.DownloadAsync(BrowserFetcher.DefaultRevision); Logger?.Debug($"Chromium downloaded to {revisionInfo.FolderPath}"); return(revisionInfo); } catch (Exception ex) { Logger?.Error($"ERROR: Failed to download Chromium r{BrowserFetcher.DefaultRevision}!)"); Logger?.Error(ex.Message); } return(null); }
public async Task ShouldDownloadAndExtractLinuxBinary() { var downloadsFolder = Path.Combine(Directory.GetCurrentDirectory(), ".test-chromium"); var browserFetcher = Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions { Platform = Platform.Linux, Path = downloadsFolder, Host = TestConstants.ServerUrl }); var revisionInfo = browserFetcher.RevisionInfo(123456); Server.SetRedirect(revisionInfo.Url.Substring(TestConstants.ServerUrl.Length), "/chromium-linux.zip"); Assert.False(revisionInfo.Local); Assert.Equal(Platform.Linux, revisionInfo.Platform); Assert.False(await browserFetcher.CanDownloadAsync(100000)); Assert.True(await browserFetcher.CanDownloadAsync(123456)); revisionInfo = await browserFetcher.DownloadAsync(123456); Assert.True(revisionInfo.Local); Assert.Equal("LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath)); Assert.Equal(new[] { 123456 }, browserFetcher.LocalRevisions()); browserFetcher.Remove(123456); Assert.Empty(browserFetcher.LocalRevisions()); new DirectoryInfo(downloadsFolder).Delete(true); }
public async void accessSite() { BrowserFetcherOptions bo = new BrowserFetcherOptions(); var browserFetcher = Puppeteer.CreateBrowserFetcher(bo); var revisionInfo = browserFetcher.RevisionInfo(BrowserFetcher.DefaultRevision); if (browserFetcher.LocalRevisions().Count() == 0) { revisionInfo = await browserFetcher.DownloadAsync(BrowserFetcher.DefaultRevision); } var browser = await Puppeteer.LaunchAsync(new LaunchOptions { ExecutablePath = revisionInfo.ExecutablePath, Headless = false }); var page = await browser.NewPageAsync();//gnb_login_button0 await page.GoToAsync("https://www.jejuair.net/jejuair/kr/main.do"); await page.WaitForSelectorAsync("button.gnb_login_button0"); await page.ClickAsync("button.gnb_login_button0"); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation($"{nameof( PdfTestFunction )} function processed a request."); // TODO: Move browserFetcher to startUp class Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions( )); await new BrowserFetcher( ).DownloadAsync(BrowserFetcher.DefaultRevision); log.LogInformation($"{nameof( PdfTestFunction )} downloaded browser version:{BrowserFetcher.DefaultRevision}."); var browser = await Puppeteer.LaunchAsync(new LaunchOptions( )); log.LogInformation($"{nameof( PdfTestFunction )} launched browser."); var page = await browser.NewPageAsync( ); await page.GoToAsync("https://www.google.com"); log.LogInformation($"{nameof( PdfTestFunction )} browser go to page."); var testpdf = await page.PdfDataAsync( ); log.LogInformation($"PDF size {testpdf.Length}"); await browser.CloseAsync( ); return(new FileContentResult(testpdf, "application/pdf")); }
public async Task ShouldDownloadAndExtractFirefoxLinuxBinary() { using var browserFetcher = Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions { Platform = Platform.Linux, Path = _downloadsFolder, Host = TestConstants.ServerUrl, Product = Product.Firefox }); var expectedVersion = "75.0a1"; var revisionInfo = browserFetcher.RevisionInfo(expectedVersion); Server.SetRedirect( revisionInfo.Url.Substring(TestConstants.ServerUrl.Length), "/firefox.zip"); Assert.False(revisionInfo.Local); Assert.Equal(Platform.Linux, revisionInfo.Platform); Assert.False(await browserFetcher.CanDownloadAsync("100000")); Assert.True(await browserFetcher.CanDownloadAsync(expectedVersion)); try { revisionInfo = await browserFetcher.DownloadAsync(expectedVersion); Assert.True(revisionInfo.Local); Assert.Equal("FIREFOX LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath)); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { #if NETCOREAPP //This will not be run on net4x anyway. Mono.Unix.FileAccessPermissions permissions = ConvertPermissions(LinuxSysCall.ExecutableFilePermissions); Assert.Equal(permissions, UnixFileSystemInfo.GetFileSystemEntry(revisionInfo.ExecutablePath).FileAccessPermissions & permissions); #endif } Assert.Equal(new[] { expectedVersion }, browserFetcher.LocalRevisions()); browserFetcher.Remove(expectedVersion); Assert.Empty(browserFetcher.LocalRevisions()); //Download should return data from a downloaded version //This section is not in the Puppeteer test. await browserFetcher.DownloadAsync(expectedVersion); Server.Reset(); revisionInfo = await browserFetcher.DownloadAsync(expectedVersion); Assert.True(revisionInfo.Local); Assert.Equal("FIREFOX LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath)); } finally { EnsureDownloadsFolderIsDeleted(); } }
public async Task ShouldDownloadAndExtractLinuxBinary() { var browserFetcher = Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions { Platform = Platform.Linux, Path = _downloadsFolder, Host = TestConstants.ServerUrl }); var revisionInfo = browserFetcher.RevisionInfo(123456); Server.SetRedirect(revisionInfo.Url.Substring(TestConstants.ServerUrl.Length), "/chromium-linux.zip"); Assert.False(revisionInfo.Local); Assert.Equal(Platform.Linux, revisionInfo.Platform); Assert.False(await browserFetcher.CanDownloadAsync(100000)); Assert.True(await browserFetcher.CanDownloadAsync(123456)); try { revisionInfo = await browserFetcher.DownloadAsync(123456); Assert.True(revisionInfo.Local); Assert.Equal("LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath)); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { #if NETCOREAPP //don't need to run this code if we're not netcore app since net471 won't run on NIX. And UnixFileSystemInfo is not available for net471 Assert.Equal( LinuxPermissionsSetter.ExecutableFilePermissions, UnixFileSystemInfo.GetFileSystemEntry(revisionInfo.ExecutablePath).FileAccessPermissions & LinuxPermissionsSetter.ExecutableFilePermissions); #endif } Assert.Equal(new[] { 123456 }, browserFetcher.LocalRevisions()); browserFetcher.Remove(123456); Assert.Empty(browserFetcher.LocalRevisions()); //Download should return data from a downloaded version //This section is not in the Puppeteer test. await browserFetcher.DownloadAsync(123456); Server.Reset(); revisionInfo = await browserFetcher.DownloadAsync(123456); Assert.True(revisionInfo.Local); Assert.Equal("LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath)); } finally { EnsureDownloadsFolderIsDeleted(); } }
public async Task ShouldDownloadAndExtractLinuxBinary() { var browserFetcher = Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions { Platform = Platform.Linux, Path = _downloadsFolder, Host = TestConstants.ServerUrl }); var revisionInfo = browserFetcher.RevisionInfo(123456); Server.SetRedirect(revisionInfo.Url.Substring(TestConstants.ServerUrl.Length), "/chromium-linux.zip"); Assert.False(revisionInfo.Local); Assert.Equal(Platform.Linux, revisionInfo.Platform); Assert.False(await browserFetcher.CanDownloadAsync(100000)); Assert.True(await browserFetcher.CanDownloadAsync(123456)); try { revisionInfo = await browserFetcher.DownloadAsync(123456); Assert.True(revisionInfo.Local); Assert.Equal("LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath)); if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { Assert.Equal( BrowserFetcher.BrowserPermissionsInLinux, LinuxSysCall.GetFileMode(revisionInfo.ExecutablePath) & BrowserFetcher.BrowserPermissionsInLinux); } Assert.Equal(new[] { 123456 }, browserFetcher.LocalRevisions()); browserFetcher.Remove(123456); Assert.Empty(browserFetcher.LocalRevisions()); //Download should return data from a downloaded version //This section is not in the Puppeteer test. await browserFetcher.DownloadAsync(123456); Server.Reset(); revisionInfo = await browserFetcher.DownloadAsync(123456); Assert.True(revisionInfo.Local); Assert.Equal("LINUX BINARY\n", File.ReadAllText(revisionInfo.ExecutablePath)); } finally { EnsureDownloadsFolderIsDeleted(); } }
public static IServiceCollection AddPdfGenerator(this IServiceCollection services, IConfiguration configuration) { services.TryAddSingleton(sp => { var logger = sp.GetRequiredService <ILogger <PdfGenerator> >(); var options = new BrowserFetcherOptions() { Product = Product.Chrome, Path = Path.Combine(configuration.GetValue("CHROME_CACHE_PATH", Path.GetTempPath()), "chrome/"), Platform = Platform.Linux }; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { options.Platform = Platform.Win64; } logger.LogInformation("Setting up Puppeteer to use {0} on platform {1} and caching in {2}", options.Product, options.Platform, options.Path); var fetcher = Puppeteer.CreateBrowserFetcher(options); var currentRevisions = fetcher.LocalRevisions(); if (currentRevisions.Any()) { var info = fetcher.GetRevisionInfoAsync().GetAwaiter().GetResult(); logger.LogInformation("Found cached Puppeteer {0} in {0}", info.Revision, info.ExecutablePath); if (info.Downloaded) { return(info); } } logger.LogInformation("Downloading Puppeteer"); return(fetcher.DownloadAsync().GetAwaiter().GetResult()); }); services.TryAddScoped <IPdfGenerator, PdfGenerator>(); return(services); }
/// <summary> /// <para>设置一个 Chromium 浏览器 启动选项 的对象,并返回这个对象;此方法兼容 Windows7 / Windows Server 2008</para> /// <para>异常可能:程序运行目录下 Chromium 浏览器不可用。</para> /// </summary> /// <param name="checkIsDownload">检查 是否下载 Chromium 浏览器;默认 false</param> /// <param name="isDisplay">Chromium 运行时 是否显示界面;默认 true</param> /// <param name="args">要传递给 Chromium 浏览器实例的其他参数。( 此方法会自动传入 "--no-sandbox" 参数 ) /// <para>参考:https://peter.sh/experiments/chromium-command-line-switches/#no-sandbox </para> /// </param> /// <param name="ignoredDefaultArgs">如果给出数组,则过滤掉给定的 Puppeteer.DefaultArgs 默认参数。 /// ( 此方法会自动设置 "--enable-automation" 过滤掉这个参数 ) /// <para>参考:https://peter.sh/experiments/chromium-command-line-switches/#no-sandbox </para> /// </param> /// <returns></returns> private static async Task <LaunchOptions> SetChromiumLaunchOptions( bool checkIsDownload = false, bool isDisplay = true, string[] args = null, string[] ignoredDefaultArgs = null) { return(await Task.Run(async() => { BrowserFetcher browserFetcher = Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions()); RevisionInfo revisionInfo = browserFetcher.RevisionInfo(BrowserFetcher.DefaultRevision); #region 检查下载 Chromium if (!(revisionInfo.Downloaded && revisionInfo.Local)) { if (checkIsDownload) { #region 载地址 解析;参考于源代码:https://github.com/hardkoded/puppeteer-sharp/blob/37ea56934281209830254df3ec3ffe37c57cfac2/lib/PuppeteerSharp/BrowserFetcher.cs // https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/706915/chrome-win.zip 下载地址( 样例 ) // const string DefaultDownloadHost = "https://storage.googleapis.com"; // const int DefaultRevision = 706915; // [Platform.Linux] = "{0}/chromium-browser-snapshots/Linux_x64/{1}/{2}.zip", // [Platform.MacOS] = "{0}/chromium-browser-snapshots/Mac/{1}/{2}.zip", // [Platform.Win32] = "{0}/chromium-browser-snapshots/Win/{1}/{2}.zip", // [Platform.Win64] = "{0}/chromium-browser-snapshots/Win_x64/{1}/{2}.zip" // case Platform.Linux: // return "chrome-linux"; // case Platform.MacOS: // return "chrome-mac"; // case Platform.Win32: // case Platform.Win64: // return revision > 591479 ? "chrome-win" : "chrome-win32"; #endregion // 检查 revisionInfo.Revision 这个版本的 Chromium 浏览器 是否 可下载 bool isCan = await browserFetcher.CanDownloadAsync(revisionInfo.Revision); if (isCan) { // 下载 revisionInfo.Revision 这个版本的无头浏览器;可能需要等待一些时间 await browserFetcher.DownloadAsync(revisionInfo.Revision); } else { throw new Exception($"程序检测出 Chromium 浏览器(默认版本 {revisionInfo.Revision})无法更新!"); } } else { throw new Exception("程序运行目录下 Chromium 浏览器不可用。请开发人员检查 程序运行目录下 是否正确安装 Chromium 浏览器。"); } } #endregion #region 兼容 Windows7 / Windows Server 2008 LaunchOptions launchOptions = default(LaunchOptions); // 这个判断是为了兼容 Windows7 和 Windows Server 2008 if (OSHelper.IsWin7Under()) { launchOptions = new LaunchOptions { WebSocketFactory = async(uri, socketOptions, cancellationToken) => { WebSocket client = SystemClientWebSocket.CreateClientWebSocket(); if (client is System.Net.WebSockets.Managed.ClientWebSocket managed) { managed.Options.KeepAliveInterval = TimeSpan.FromSeconds(0); await managed.ConnectAsync(uri, cancellationToken); } else { ClientWebSocket coreSocket = client as ClientWebSocket; coreSocket.Options.KeepAliveInterval = TimeSpan.FromSeconds(0); await coreSocket.ConnectAsync(uri, cancellationToken); } return client; } }; } else { launchOptions = new LaunchOptions(); } #endregion #region 设置 Args 参数 string[] argss = default(string[]); if (args != null && args.Length > 0) { List <string> argsList = args.ToList <string>(); argsList.Add("--no-sandbox"); argss = argsList.ToArray(); } else { argss = new string[] { "--no-sandbox" }; } launchOptions.Args = argss; //这些参数将会传递给 Chromium #endregion #region 设置 IgnoredDefaultArgs 参数 string[] defaultArgs = default(string[]); if (ignoredDefaultArgs != null && ignoredDefaultArgs.Length > 0) { List <string> ignoredDefaultArgsList = ignoredDefaultArgs.ToList <string>(); ignoredDefaultArgsList.Add("--enable-automation"); defaultArgs = ignoredDefaultArgsList.ToArray(); } else { defaultArgs = new string[] { "--enable-automation" }; } launchOptions.IgnoredDefaultArgs = defaultArgs; //这些参数将被 Chromium 忽略 #endregion launchOptions.Headless = !isDisplay; // Headless : true 是无头模式,无界面;false,有界面 return launchOptions; })); }
/// <summary> /// <para>设置一个 Chromium 浏览器 启动选项 的对象,并返回这个对象;此方法兼容 Windows7 / Windows Server 2008</para> /// <para>异常可能:程序运行目录下 Chromium 浏览器不可用。</para> /// </summary> /// <param name="checkIsDownload">检查 是否下载 Chromium 浏览器;默认 false</param> /// <param name="isDisplay">Chromium 运行时 是否显示界面;默认 true</param> /// <param name="args">要传递给 Chromium 浏览器实例的其他参数。( 此方法会自动传入 "--no-sandbox" 参数 ) /// <para>参考:https://peter.sh/experiments/chromium-command-line-switches/#no-sandbox </para> /// </param> /// <param name="ignoredDefaultArgs">如果给出数组,则过滤掉给定的 Puppeteer.DefaultArgs 默认参数。 /// ( 此方法会自动设置 "--enable-automation" 过滤掉这个参数 ) /// <para>参考:https://peter.sh/experiments/chromium-command-line-switches/#no-sandbox </para> /// </param> /// <returns></returns> private static async Task <LaunchOptions> SetChromiumLaunchOptions( bool checkIsDownload = false, bool isDisplay = true, string[] args = null, string[] ignoredDefaultArgs = null) { return(await Task.Run(async() => { BrowserFetcher browserFetcher = Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions()); RevisionInfo revisionInfo = browserFetcher.RevisionInfo(BrowserFetcher.DefaultChromiumRevision); #region 检查下载 Chromium if (!(revisionInfo.Downloaded && revisionInfo.Local)) { if (checkIsDownload) { // 检查 revisionInfo.Revision 这个版本的 Chromium 浏览器 是否 可下载 bool isCan = await browserFetcher.CanDownloadAsync(revisionInfo.Revision); if (isCan) { // 下载 revisionInfo.Revision 这个版本的无头浏览器;可能需要等待一些时间 await browserFetcher.DownloadAsync(revisionInfo.Revision); } else { throw new Exception($"程序检测出 Chromium 浏览器(默认版本 {revisionInfo.Revision})无法更新!"); } } else { throw new Exception("程序运行目录下 Chromium 浏览器不可用。请开发人员检查 程序运行目录下 是否正确安装 Chromium 浏览器。"); } } #endregion #region 兼容 Windows7 / Windows Server 2008 LaunchOptions launchOptions = default(LaunchOptions); // 这个判断是为了兼容 Windows7 和 Windows Server 2008 if (OSHelper.IsWin7Under()) { launchOptions = new LaunchOptions { WebSocketFactory = async(uri, socketOptions, cancellationToken) => { WebSocket client = SystemClientWebSocket.CreateClientWebSocket(); if (client is System.Net.WebSockets.Managed.ClientWebSocket managed) { managed.Options.KeepAliveInterval = TimeSpan.FromSeconds(0); await managed.ConnectAsync(uri, cancellationToken); } else { ClientWebSocket coreSocket = client as ClientWebSocket; coreSocket.Options.KeepAliveInterval = TimeSpan.FromSeconds(0); await coreSocket.ConnectAsync(uri, cancellationToken); } return client; } }; } else { launchOptions = new LaunchOptions(); } #endregion #region 设置 Args 参数 string[] argss = default(string[]); if (args != null && args.Length > 0) { List <string> argsList = args.ToList <string>(); argsList.Add("--no-sandbox"); argss = argsList.ToArray(); } else { argss = new string[] { "--no-sandbox" }; } launchOptions.Args = argss; // 这些参数将会传递给 Chromium #endregion #region 设置 IgnoredDefaultArgs 参数 string[] defaultArgs = default(string[]); if (ignoredDefaultArgs != null && ignoredDefaultArgs.Length > 0) { List <string> ignoredDefaultArgsList = ignoredDefaultArgs.ToList <string>(); ignoredDefaultArgsList.Add("--enable-automation"); defaultArgs = ignoredDefaultArgsList.ToArray(); } else { defaultArgs = new string[] { "--enable-automation" }; } launchOptions.IgnoredDefaultArgs = defaultArgs; // 这些参数将被 Chromium 忽略 #endregion launchOptions.Headless = !isDisplay; // Headless : true 是无头模式,无界面;false,有界面 return launchOptions; })); }
// 无头浏览器测试 private void btn_chromiumTest_Click(object sender, EventArgs e) { this.Invoke(new Action(() => { this.btn_chromiumTest.Enabled = false; this.rTxt_log.Clear(); })); Task.Run(async() => { #region 无头浏览器下载更新 BrowserFetcher browserFetcher = Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions()); RevisionInfo revisionInfo = browserFetcher.RevisionInfo(BrowserFetcher.DefaultChromiumRevision); if (revisionInfo.Downloaded && revisionInfo.Local) { this.Invoke(new Action(() => { this.rTxt_log.AppendText("无头浏览器检查完成,无需更新! \n"); })); } else { this.Invoke(new Action(() => { this.rTxt_log.AppendText("无头浏览器检查完成,需要更新! \n"); this.rTxt_log.AppendText("正在检查更新... \n"); })); // 检查 revisionInfo.Revision 这个版本的 Chromium 浏览器 是否 可下载 bool isCan = await browserFetcher.CanDownloadAsync(revisionInfo.Revision); if (!isCan) { this.Invoke(new Action(() => { this.rTxt_log.AppendText($"程序检测出无头浏览器(默认版本 {revisionInfo.Revision})无法更新! \n"); this.btn_chromiumTest.Enabled = true; })); return; } this.Invoke(new Action(() => { this.rTxt_log.AppendText("正在更新无头浏览器... \n"); })); // 下载 revisionInfo.Revision 这个版本的无头浏览器;可能需要等待一些时间 await browserFetcher.DownloadAsync(revisionInfo.Revision); this.Invoke(new Action(() => { this.rTxt_log.AppendText("无头浏览器更新完成。 \n"); })); } #endregion this.Invoke(new Action(() => { this.rTxt_log.AppendText("开始测试无头浏览器... \n"); })); await TestHeadlessChromiumAsync(); this.Invoke(new Action(() => { this.rTxt_log.AppendText("无头浏览器测试完成。 \n"); this.btn_chromiumTest.Enabled = true; })); }); }
// 无头浏览器测试 private void btn_chromiumTest_Click(object sender, EventArgs e) { this.Invoke(new Action(() => { this.btn_chromiumTest.Enabled = false; this.rTxt_log.Clear(); })); Task.Run(async() => { #region 无头浏览器下载更新 BrowserFetcher browserFetcher = Puppeteer.CreateBrowserFetcher(new BrowserFetcherOptions()); RevisionInfo revisionInfo = browserFetcher.RevisionInfo(BrowserFetcher.DefaultRevision); #region 载地址 解析;参考于源代码:https://github.com/hardkoded/puppeteer-sharp/blob/37ea56934281209830254df3ec3ffe37c57cfac2/lib/PuppeteerSharp/BrowserFetcher.cs // https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/706915/chrome-win.zip 下载地址( 样例 ) // const string DefaultDownloadHost = "https://storage.googleapis.com"; // const int DefaultRevision = 706915; // [Platform.Linux] = "{0}/chromium-browser-snapshots/Linux_x64/{1}/{2}.zip", // [Platform.MacOS] = "{0}/chromium-browser-snapshots/Mac/{1}/{2}.zip", // [Platform.Win32] = "{0}/chromium-browser-snapshots/Win/{1}/{2}.zip", // [Platform.Win64] = "{0}/chromium-browser-snapshots/Win_x64/{1}/{2}.zip" // case Platform.Linux: // return "chrome-linux"; // case Platform.MacOS: // return "chrome-mac"; // case Platform.Win32: // case Platform.Win64: // return revision > 591479 ? "chrome-win" : "chrome-win32"; #endregion if (revisionInfo.Downloaded && revisionInfo.Local) { this.Invoke(new Action(() => { this.rTxt_log.AppendText("无头浏览器检查完成,无需更新! \n"); })); } else { this.Invoke(new Action(() => { this.rTxt_log.AppendText("无头浏览器检查完成,需要更新! \n"); this.rTxt_log.AppendText("正在检查更新... \n"); })); // 检查 revisionInfo.Revision 这个版本的 Chromium 浏览器 是否 可用\可下载 bool isCan = await browserFetcher.CanDownloadAsync(revisionInfo.Revision); if (!isCan) { this.Invoke(new Action(() => { this.rTxt_log.AppendText($"程序检测出无头浏览器(默认版本 {revisionInfo.Revision})无法更新! \n"); this.btn_chromiumTest.Enabled = true; })); return; } this.Invoke(new Action(() => { this.rTxt_log.AppendText("正在更新无头浏览器... \n"); })); // 下载 revisionInfo.Revision 这个版本的无头浏览器;可能需要等待一些时间 await browserFetcher.DownloadAsync(revisionInfo.Revision); this.Invoke(new Action(() => { this.rTxt_log.AppendText("无头浏览器更新完成。 \n"); })); } #endregion this.Invoke(new Action(() => { this.rTxt_log.AppendText("开始测试无头浏览器... \n"); })); await TestHeadlessChromiumAsync(); this.Invoke(new Action(() => { this.rTxt_log.AppendText("无头浏览器测试完成。 \n"); this.btn_chromiumTest.Enabled = true; })); }); }