예제 #1
0
파일: GeckoPdf.cs 프로젝트: shekky/GeckoPdf
        private byte[] ConvertToPdf(string url, string html, string tempFilePath, NameValueCollection headers = null, IEnumerable <GeckoCookie> cookies = null)
        {
            // Initialize gecko engine
            if (!HeadlessGecko.IsInitialized)
            {
                var initSignal = new SemaphoreSlim(0, 1);
                HeadlessGecko.OnInitialized += () =>
                {
                    initSignal.Release();
                };

                HeadlessGecko.Initialize(GeckoBinDirectory);
                initSignal.Wait();
            }

            var printReadySignal = new SemaphoreSlim(0, 1);

            var browser = HeadlessGecko.CreateBrowser();

            browser.DocumentCompleted += (s, e) =>
            {
                // After loading document, waits some time, and send print ready signal
                Task.Run(() =>
                {
                    Thread.Sleep(1000); // Some delay need, otherwise throws COMException
                    printReadySignal.Release();
                });
            };


            // Invoke navigate method in STA browser thread
            browser.Invoke((MethodInvoker) delegate
            {
                Uri uri          = null;
                var isUriSuccess = Uri.TryCreate(url, UriKind.Absolute, out uri);

                if (isUriSuccess && cookies != null)
                {
                    foreach (var cookie in cookies)
                    {
                        CookieManager.Add(uri.Host, cookie.Path, cookie.Name, cookie.Value, cookie.Secure, cookie.HttpOnly, false, cookie.ExpiresUnix);
                    }
                }
                var geckoHeaders = MimeInputStream.Create();
                if (headers != null)
                {
                    var headersItems = headers.AllKeys.SelectMany(headers.GetValues, (k, v) => new { Key = k, Value = v });
                    foreach (var header in headersItems)
                    {
                        geckoHeaders.AddHeader(header.Key, header.Value);
                    }
                    return;
                }
                else
                {
                    geckoHeaders.AddHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0");
                    geckoHeaders.AddHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
                    geckoHeaders.AddHeader("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3");
                    geckoHeaders.AddHeader("Accept-Encoding", "gzip, deflate, br");
                    geckoHeaders.AddHeader("X-Compress", "1");
                    geckoHeaders.AddHeader("Connection", "keep-alive");
                }

                if (string.IsNullOrEmpty(html))
                {
                    browser.Navigate(url, GeckoLoadFlags.None, url, null, geckoHeaders);
                }
                else
                {
                    browser.LoadHtml(html, url);
                }
            });

            printReadySignal.Wait(); // Waiting before print will completed
            //browser.NavigateFinishedNotifier.BlockUntilNavigationFinished();

            // Create temporary file and print page to him
            if (string.IsNullOrEmpty(tempFilePath))
            {
                tempFilePath = Path.GetTempFileName();
            }

            var fi = new FileInfo(tempFilePath);

            if (!fi.Exists)
            {
                if (!fi.Directory.Exists)
                {
                    fi.Directory.Create();
                }
                File.Create(tempFilePath).Close();
            }

            browser.Invoke((MethodInvoker) delegate
            {
                browser.PrintToFile(_config, tempFilePath);
            });

            var attempts = 0;

            while (Tools.IsFileLocked(tempFilePath) || attempts >= _config.MaxLockingCheckAttempts)
            {
                attempts++;
                Thread.Sleep(_config.PdfLockingCheckDelay);
            }

            if (attempts >= _config.MaxLockingCheckAttempts)
            {
                throw new IOException("Generated pdf file locked too long");
            }

            // Read temporary file to MemoryStream and delete
            var bytes = File.ReadAllBytes(tempFilePath);

            File.Delete(tempFilePath);

            browser.Invoke((MethodInvoker) delegate
            {
                browser.Dispose();
            });

            return(bytes);
        }
예제 #2
0
파일: GeckoPdf.cs 프로젝트: shekky/GeckoPdf
 /// <summary>
 /// Unloads gecko engine. Need to be invoked always, when application shutdown
 /// </summary>
 public static void UnloadGecko()
 {
     HeadlessGecko.Unload();
 }