/// <summary>
        /// Gets the executable path.
        /// </summary>
        /// <returns>The executable path.</returns>
        public static string GetExecutablePath()
        {
            var downloader   = Downloader.CreateDefault();
            var revisionInfo = downloader.RevisionInfo(Downloader.CurrentPlatform, Downloader.DefaultRevision);

            return(revisionInfo.ExecutablePath);
        }
        /// <summary>
        /// The method launches a browser instance with given arguments. The browser will be closed when the Browser is disposed.
        /// </summary>
        /// <param name="options">Options for launching Chrome</param>
        /// <param name="chromiumRevision">The revision of Chrome to launch.</param>
        /// <returns>A connected browser.</returns>
        /// <remarks>
        /// See <a href="https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/">this article</a>
        /// for a description of the differences between Chromium and Chrome.
        /// <a href="https://chromium.googlesource.com/chromium/src/+/lkcr/docs/chromium_browser_vs_google_chrome.md">This article</a> describes some differences for Linux users.
        /// </remarks>
        public async Task <Browser> LaunchAsync(LaunchOptions options, int chromiumRevision)
        {
            if (_chromiumLaunched)
            {
                throw new InvalidOperationException("Unable to create or connect to another chromium process");
            }
            _chromiumLaunched = true;
            var chromeArguments  = InitChromeArgument(options);
            var chromeExecutable = options.ExecutablePath;

            if (string.IsNullOrEmpty(chromeExecutable))
            {
                var downloader   = Downloader.CreateDefault();
                var revisionInfo = downloader.RevisionInfo(Downloader.CurrentPlatform, chromiumRevision);
                chromeExecutable = revisionInfo.ExecutablePath;
            }
            if (!File.Exists(chromeExecutable))
            {
                throw new FileNotFoundException("Failed to launch chrome! path to executable does not exist", chromeExecutable);
            }

            CreateChromeProcess(options, chromeArguments, chromeExecutable);

            try
            {
                var connectionDelay   = options.SlowMo;
                var browserWSEndpoint = await WaitForEndpoint(_chromeProcess, options.Timeout, options.DumpIO);

                var keepAliveInterval = options.KeepAliveInterval;

                _connection = await Connection.Create(browserWSEndpoint, connectionDelay, keepAliveInterval, _loggerFactory);

                _processLoaded = true;

                if (options.LogProcess)
                {
                    _logger.LogInformation("Process Count: {ProcessCount}", Interlocked.Increment(ref _processCount));
                }

                return(await Browser.CreateAsync(_connection, options, _chromeProcess, KillChrome));
            }
            catch (Exception ex)
            {
                ForceKillChrome();
                throw new ChromeProcessException("Failed to create connection", ex);
            }
        }
Beispiel #3
0
        /// <summary>
        /// The method launches a browser instance with given arguments. The browser will be closed when the Browser is disposed.
        /// </summary>
        /// <param name="options">Options for launching Chrome</param>
        /// <param name="chromiumRevision">The revision of Chrome to launch.</param>
        /// <returns>A connected browser.</returns>
        /// <remarks>
        /// See <a href="https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/">this article</a>
        /// for a description of the differences between Chromium and Chrome.
        /// <a href="https://chromium.googlesource.com/chromium/src/+/lkcr/docs/chromium_browser_vs_google_chrome.md">This article</a> describes some differences for Linux users.
        /// </remarks>
        public async Task <Browser> LaunchAsync(LaunchOptions options, int chromiumRevision)
        {
            var chromeArguments = new List <string>(DefaultArgs);

            _options = options;

            if (options.AppMode)
            {
                options.Headless = false;
            }
            else
            {
                chromeArguments.AddRange(AutomationArgs);
            }

            var userDataDirOption = options.Args.FirstOrDefault(i => i.StartsWith(UserDataDirArgument, StringComparison.Ordinal));

            if (string.IsNullOrEmpty(userDataDirOption))
            {
                if (string.IsNullOrEmpty(options.UserDataDir))
                {
                    _temporaryUserDataDir = GetTemporaryDirectory();
                    chromeArguments.Add($"{UserDataDirArgument}={_temporaryUserDataDir}");
                }
                else
                {
                    chromeArguments.Add($"{UserDataDirArgument}={options.UserDataDir}");
                }
            }
            else
            {
                _options.UserDataDir = userDataDirOption.Replace($"{UserDataDirArgument}=", string.Empty);
            }

            if (options.Devtools)
            {
                chromeArguments.Add("--auto-open-devtools-for-tabs");
                options.Headless = false;
            }

            if (options.Headless)
            {
                chromeArguments.AddRange(new[] {
                    "--headless",
                    "--disable-gpu",
                    "--hide-scrollbars",
                    "--mute-audio"
                });
            }

            var chromeExecutable = options.ExecutablePath;

            if (string.IsNullOrEmpty(chromeExecutable))
            {
                var downloader   = Downloader.CreateDefault();
                var revisionInfo = downloader.RevisionInfo(Downloader.CurrentPlatform, chromiumRevision);
                chromeExecutable = revisionInfo.ExecutablePath;
            }
            if (!File.Exists(chromeExecutable))
            {
                throw new FileNotFoundException("Failed to launch chrome! path to executable does not exist", chromeExecutable);
            }

            if (options.Args.Any())
            {
                chromeArguments.AddRange(options.Args);
            }

            _chromeProcess = new Process();
            _chromeProcess.EnableRaisingEvents       = true;
            _chromeProcess.StartInfo.UseShellExecute = false;
            _chromeProcess.StartInfo.FileName        = chromeExecutable;
            _chromeProcess.StartInfo.Arguments       = string.Join(" ", chromeArguments);

            SetEnvVariables(_chromeProcess.StartInfo.Environment, options.Env, Environment.GetEnvironmentVariables());

            if (!options.DumpIO)
            {
                _chromeProcess.StartInfo.RedirectStandardOutput = false;
                _chromeProcess.StartInfo.RedirectStandardError  = false;
            }

            _chromeProcess.Exited += async(sender, e) =>
            {
                await AfterProcessExit();
            };

            try
            {
                var connectionDelay   = options.SlowMo;
                var browserWSEndpoint = await WaitForEndpoint(_chromeProcess, options.Timeout, options.DumpIO);

                var keepAliveInterval = options.KeepAliveInterval;

                _connection = await Connection.Create(browserWSEndpoint, connectionDelay, keepAliveInterval);

                _processLoaded = true;

                if (options.LogProcess)
                {
                    Console.WriteLine($"PROCESS COUNT: {Interlocked.Increment(ref _processCount)}");
                }

                return(await Browser.CreateAsync(_connection, options, _chromeProcess, KillChrome));
            }
            catch (Exception ex)
            {
                ForceKillChrome();
                throw new ChromeProcessException("Failed to create connection", ex);
            }
        }
Beispiel #4
0
        internal static async Task <Browser> LaunchAsync(Dictionary <string, object> options, int chromiumRevision)
        {
            var chromeArguments = new List <string>(_defaultArgs);

            if (options.ContainsKey("appMode"))
            {
                options["headless"] = false;
            }
            else
            {
                chromeArguments.AddRange(_automationArgs);
            }

            if (options.ContainsKey("args") &&
                ((string[])options["args"]).Any(i => i.StartsWith("--user-data-dir", StringComparison.Ordinal)))
            {
                if (!options.ContainsKey("userDataDir"))
                {
                    _temporaryUserDataDir = GetTemporaryDirectory();
                    chromeArguments.Add($"--user-data-dir=${_temporaryUserDataDir}");
                }
                else
                {
                    chromeArguments.Add($"--user-data-dir=${options["userDataDir"]}");
                }
            }

            if (options.TryGetValue("devtools", out var hasDevTools) && (bool)hasDevTools)
            {
                chromeArguments.Add("--auto-open-devtools-for-tabs");
                options["headless"] = false;
            }

            if (options.TryGetValue("headless", out var isHeadless) && (bool)isHeadless)
            {
                chromeArguments.AddRange(new[] {
                    "--headless",
                    "--disable-gpu",
                    "--hide-scrollbars",
                    "--mute-audio"
                });
            }

            var chromeExecutable = (options.GetValueOrDefault("executablePath") ?? "").ToString();

            if (string.IsNullOrEmpty(chromeExecutable))
            {
                var downloader   = Downloader.CreateDefault();
                var revisionInfo = downloader.RevisionInfo(Downloader.CurrentPlatform, chromiumRevision);
                chromeExecutable = revisionInfo.ExecutablePath;
            }

            if (options.ContainsKey("args"))
            {
                chromeArguments.AddRange((string[])options["args"]);
            }

            _chromeProcess = new Process();
            _chromeProcess.StartInfo.FileName  = chromeExecutable;
            _chromeProcess.StartInfo.Arguments = string.Join(" ", chromeArguments);

            SetEnvVariables(_chromeProcess.StartInfo.Environment,
                            options.ContainsKey("env") ? (IDictionary <string, string>)options["env"] : null,
                            (IDictionary)Environment.GetEnvironmentVariables());

            if (!options.ContainsKey("dumpio"))
            {
                _chromeProcess.StartInfo.RedirectStandardOutput = false;
                _chromeProcess.StartInfo.RedirectStandardError  = false;
            }

            _chromeProcess.Exited += async(sender, e) =>
            {
                _chromeClosed = true;
                await KillChrome();
            };

            try
            {
                var connectionDelay   = (int)(options.GetValueOrDefault("slowMo") ?? 0);
                var browserWSEndpoint = await WaitForEndpoint(_chromeProcess,
                                                              (int)(options.GetValueOrDefault("timeout") ?? 30 * 100),
                                                              options.ContainsKey("dumpio"));

                _connection = await Connection.Create(browserWSEndpoint, connectionDelay);

                return(await Browser.CreateAsync(_connection, options, KillChrome));
            }
            catch (Exception ex)
            {
                await ForceKillChrome();

                throw new Exception("Failed to create connection", ex);
            }
        }