diff --git a/dotnet/src/webdriver/DriverService.cs b/dotnet/src/webdriver/DriverService.cs
index 2770fc245f9b9..2da6a6aef7904 100644
--- a/dotnet/src/webdriver/DriverService.cs
+++ b/dotnet/src/webdriver/DriverService.cs
@@ -65,7 +65,23 @@ protected DriverService(string servicePath, int port, string driverServiceExecut
string executablePath = Path.Combine(servicePath, driverServiceExecutableName);
if (!File.Exists(executablePath))
{
- throw new DriverServiceNotFoundException(string.Format(CultureInfo.InvariantCulture, "The file {0} does not exist. The driver can be downloaded at {1}", executablePath, driverServiceDownloadUrl));
+ try
+ {
+ executablePath = SeleniumManager.DriverPath(driverServiceExecutableName);
+ }
+ catch (Exception e)
+ {
+ // No-op; entirely a fall-back feature
+ }
+
+ if (File.Exists(executablePath))
+ {
+ servicePath = Path.GetDirectoryName(executablePath);
+ }
+ else
+ {
+ throw new DriverServiceNotFoundException(string.Format(CultureInfo.InvariantCulture, "The file {0} does not exist. The driver can be downloaded at {1}", executablePath, driverServiceDownloadUrl));
+ }
}
this.driverServicePath = servicePath;
@@ -74,12 +90,12 @@ protected DriverService(string servicePath, int port, string driverServiceExecut
}
///
- /// Occurs when the driver process is starting.
+ /// Occurs when the driver process is starting.
///
public event EventHandler DriverProcessStarting;
///
- /// Occurs when the driver process has completely started.
+ /// Occurs when the driver process has completely started.
///
public event EventHandler DriverProcessStarted;
diff --git a/dotnet/src/webdriver/SeleniumManager.cs b/dotnet/src/webdriver/SeleniumManager.cs
new file mode 100644
index 0000000000000..18ccbb820ef3c
--- /dev/null
+++ b/dotnet/src/webdriver/SeleniumManager.cs
@@ -0,0 +1,146 @@
+//
+// Licensed to the Software Freedom Conservancy (SFC) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The SFC licenses this file
+// to you under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Threading;
+using OpenQA.Selenium.Internal;
+
+namespace OpenQA.Selenium
+{
+ ///
+ /// Wrapper for the Selenium Manager binary.
+ ///
+ public static class SeleniumManager
+ {
+ private static string binary;
+ private static readonly List KnownDrivers = new List() {
+ "geckodriver.exe",
+ "chromedriver.exe"
+ };
+
+ ///
+ /// Determines the location of the correct driver.
+ ///
+ /// Which driver the service needs.
+ ///
+ /// The location of the driver.
+ ///
+ public static string DriverPath(string driverName)
+ {
+ if (!KnownDrivers.Contains(driverName))
+ {
+ throw new WebDriverException("Unable to locate driver with name: " + driverName);
+ }
+ var binaryFile = Binary;
+ if (binaryFile == null) return null;
+
+ var arguments = "--driver " + driverName.Replace(".exe", "");
+ var output = RunCommand(binaryFile, arguments);
+ return output.Replace("INFO\t", "").TrimEnd();
+ }
+
+ ///
+ /// Gets the location of the correct Selenium Manager binary.
+ ///
+ private static string Binary
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(binary))
+ {
+ string folder = "windows";
+ string extension = ".exe";
+
+ if (!Environment.OSVersion.Platform.ToString().StartsWith("Win"))
+ {
+ throw new WebDriverException("Selenium Manager only supports Windows in .NET at this time");
+ }
+
+ try
+ {
+ string name = "selenium-manager-" + folder;
+ using (Stream fileStream = ResourceUtilities.GetResourceStream(name, name))
+ {
+ using (BinaryReader binReader = new BinaryReader(fileStream, Encoding.ASCII))
+ {
+ byte[] fileBytes = binReader.ReadBytes((int)fileStream.Length);
+ string directoryName = string.Format(CultureInfo.InvariantCulture, "webdriver.{0}",
+ Guid.NewGuid().ToString("N"));
+ var path = Path.Combine(Path.GetTempPath(), directoryName + "/" + folder);
+ Directory.CreateDirectory(path);
+ var filePath = Path.Combine(path, "selenium-manager" + extension);
+
+ using (BinaryWriter binWriter = new BinaryWriter(File.Open(filePath, FileMode.Create)))
+ {
+ binWriter.Flush();
+ binWriter.Write(fileBytes);
+ }
+ binary = filePath;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new WebDriverException("Unable to obtain Selenium Manager", ex);
+ }
+ }
+
+ return binary;
+ }
+ }
+
+ ///
+ /// Executes a process with the given arguments.
+ ///
+ /// The path to the Selenium Manager.
+ /// The switches to be used by Selenium Manager.
+ ///
+ /// the standard output of the execution.
+ ///
+ private static string RunCommand(string fileName, string arguments)
+ {
+ Process process = new Process();
+ process.StartInfo.FileName = fileName;
+ process.StartInfo.Arguments = arguments;
+ process.StartInfo.UseShellExecute = false;
+ process.StartInfo.RedirectStandardOutput = true;
+
+ try
+ {
+ process.Start();
+ }
+ catch (Exception ex)
+ {
+ throw new WebDriverException("Error starting process: " + process, ex);
+ }
+
+ String output = process.StandardOutput.ReadToEnd();
+
+ if (!output.StartsWith("INFO")) {
+ throw new WebDriverException("Invalid response from process: " + process);
+ }
+
+ return output;
+ }
+ }
+}
diff --git a/dotnet/src/webdriver/WebDriver.csproj b/dotnet/src/webdriver/WebDriver.csproj
index f2c128b22c308..ab7a074a9da3e 100644
--- a/dotnet/src/webdriver/WebDriver.csproj
+++ b/dotnet/src/webdriver/WebDriver.csproj
@@ -117,6 +117,10 @@
False
webdriver_prefs.json
+
+ False
+ selenium-manager-windows
+
False
get-attribute.js
@@ -140,6 +144,10 @@
False
webdriver_prefs.json
+
+ False
+ selenium-manager-windows
+
False
get-attribute.js