Пример #1
0
        public async Task <byte[]> ConvertHtmlToPdf(string html, string cssPath)
        {
            var pdfOptions = new PdfOptions();

            var browserFetcher = new BrowserFetcher(new BrowserFetcherOptions
            {
                Path = _chromiumPath
            });

            await browserFetcher.DownloadAsync(BrowserFetcher.DefaultRevision);

            using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                ExecutablePath = browserFetcher.RevisionInfo(BrowserFetcher.DefaultRevision).ExecutablePath,
                Headless       = true
            });

            var page = await browser.NewPageAsync();

            await page.SetContentAsync(html);

            await page.AddStyleTagAsync(new AddTagOptions { Path = cssPath });

            var stream = await page.PdfStreamAsync(pdfOptions);

            using var ms = new MemoryStream();
            await stream.CopyToAsync(ms);

            return(ms.ToArray());
        }
Пример #2
0
        static PicGen()
        {
            var downloadsFolder = Path.GetTempPath();
            var option          = new BrowserFetcherOptions
            {
                Path = downloadsFolder
            };
            var fetcher = new BrowserFetcher(option);

            fetcher.DownloadAsync(BrowserFetcher.DefaultRevision).Wait();
            var browser = Puppeteer.LaunchAsync(new LaunchOptions
            {
                ExecutablePath = fetcher.RevisionInfo(BrowserFetcher.DefaultRevision).ExecutablePath,
                Headless       = true,
                Args           = new[]
                {
                    !isProd ? "--proxy-server=winip:1080" : ""
                }
            }).Result;

            page = browser.NewPageAsync().Result;
            page.SetViewportAsync(new ViewPortOptions
            {
                Height = 800,
                Width  = 1300
            }).Wait();
        }
        /// <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;
            }));
        }
Пример #4
0
 public static RevisionInfo RevisionInfo(int revision)
 {
     return(BrowserFetcher.RevisionInfo(revision != 0 ? revision : BrowserFetcher.DefaultRevision));
 }
        /// <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;
            }));
        }
Пример #6
0
        private async Task <RevisionInfo> EnsureDownloadsAsync()
        {
            var browserFetcher = new BrowserFetcher(new BrowserFetcherOptions
            {
                Path = GetDownloadsDirectory(),
            });
            var desiredRevision = BrowserFetcher.DefaultRevision;
            var revisionInfo    = browserFetcher.RevisionInfo(desiredRevision);

            if (revisionInfo.Downloaded && revisionInfo.Local)
            {
                _logger.LogDebug(
                    "Using Chromium revision {Revision} for {Platform}.",
                    revisionInfo.Revision,
                    revisionInfo.Platform);
            }
            else
            {
                _logger.LogInformation(
                    $"Downloading Chromium revision {{Revision}} for {{Platform}} to:{Environment.NewLine}{{FolderPath}}",
                    revisionInfo.Revision,
                    revisionInfo.Platform,
                    revisionInfo.FolderPath);

                // Set up the progress report.
                long?contentLength;
                using (var httpClient = new HttpClient())
                    using (var request = new HttpRequestMessage(HttpMethod.Head, revisionInfo.Url))
                        using (var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead))
                        {
                            contentLength = response.Content.Headers.ContentLength;
                        }

                long progressIncrement;
                if (contentLength.HasValue)
                {
                    _logger.LogDebug("The download will be {Bytes:N0} bytes.", contentLength);

                    // 5%
                    progressIncrement = 5;
                }
                else
                {
                    // 1 megabyte
                    progressIncrement = 1024 * 1024;
                }

                long nextProgress = 0;
                var  progressLock = new object();
                browserFetcher.DownloadProgressChanged += (sender, e) =>
                {
                    lock (progressLock)
                    {
                        if (contentLength.HasValue)
                        {
                            var progressPercentage = (int)Math.Round((100.0 * e.BytesReceived) / contentLength.Value);
                            if (progressPercentage > nextProgress)
                            {
                                _logger.LogInformation("Download progress: {Percentage}%", progressPercentage);
                                nextProgress += progressIncrement;
                            }
                        }
                        else
                        {
                            if (e.BytesReceived > nextProgress)
                            {
                                _logger.LogInformation("Download progress: {BytesReceived:N0} bytes", e.BytesReceived);
                                nextProgress += progressIncrement;
                            }
                        }
                    }
                };

                // Start the download.
                revisionInfo = await browserFetcher.DownloadAsync(desiredRevision);

                if (contentLength.HasValue)
                {
                    _logger.LogInformation("Download progress: {Percentage}%", 100);
                }

                _logger.LogInformation("Chromium is done downloading.");
            }

            return(revisionInfo);
        }
Пример #7
0
        // 无头浏览器测试
        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;
                }));
            });
        }
Пример #8
0
        // 无头浏览器测试
        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;
                }));
            });
        }