chromiumoxide/
detection.rs1use std::env;
2use std::path::{Path, PathBuf};
3
4#[derive(Debug, Clone)]
5pub struct DetectionOptions {
6 pub msedge: bool,
8 pub unstable: bool,
10}
11
12impl Default for DetectionOptions {
13 fn default() -> Self {
14 Self {
15 msedge: true,
16 unstable: false,
17 }
18 }
19}
20
21pub fn default_executable(options: DetectionOptions) -> Result<std::path::PathBuf, String> {
30 if let Some(path) = get_by_env_var() {
31 return Ok(path);
32 }
33
34 if let Some(path) = get_by_name(&options) {
35 return Ok(path);
36 }
37
38 #[cfg(windows)]
39 if let Some(path) = get_by_registry() {
40 return Ok(path);
41 }
42
43 if let Some(path) = get_by_path(&options) {
44 return Ok(path);
45 }
46
47 Err("Could not auto detect a chrome executable".to_string())
48}
49
50fn get_by_env_var() -> Option<PathBuf> {
51 if let Ok(path) = env::var("CHROME") {
52 if Path::new(&path).exists() {
53 return Some(path.into());
54 }
55 }
56
57 None
58}
59
60fn get_by_name(options: &DetectionOptions) -> Option<PathBuf> {
61 let default_apps = [
62 ("chrome", true),
63 ("chrome-browser", true),
64 ("google-chrome-stable", true),
65 ("google-chrome-beta", options.unstable),
66 ("google-chrome-dev", options.unstable),
67 ("google-chrome-unstable", options.unstable),
68 ("chromium", true),
69 ("chromium-browser", true),
70 ("msedge", options.msedge),
71 ("microsoft-edge", options.msedge),
72 ("microsoft-edge-stable", options.msedge),
73 ("microsoft-edge-beta", options.msedge && options.unstable),
74 ("microsoft-edge-dev", options.msedge && options.unstable),
75 ];
76 for (app, allowed) in default_apps {
77 if !allowed {
78 continue;
79 }
80 if let Ok(path) = which::which(app) {
81 return Some(path);
82 }
83 }
84
85 None
86}
87
88#[allow(unused_variables)]
89fn get_by_path(options: &DetectionOptions) -> Option<PathBuf> {
90 #[cfg(all(unix, not(target_os = "macos")))]
91 let default_paths: [(&str, bool); 3] = [
92 ("/opt/chromium.org/chromium", true),
93 ("/opt/google/chrome", true),
94 ("/tmp/aws/lib", true),
96 ];
97 #[cfg(windows)]
98 let default_paths = [(
99 r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe",
100 options.msedge,
101 )];
102 #[cfg(target_os = "macos")]
103 let default_paths = [
104 (
105 "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
106 true,
107 ),
108 (
109 "/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta",
110 options.unstable,
111 ),
112 (
113 "/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev",
114 options.unstable,
115 ),
116 (
117 "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
118 options.unstable,
119 ),
120 ("/Applications/Chromium.app/Contents/MacOS/Chromium", true),
121 (
122 "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
123 options.msedge,
124 ),
125 (
126 "/Applications/Microsoft Edge Beta.app/Contents/MacOS/Microsoft Edge Beta",
127 options.msedge && options.unstable,
128 ),
129 (
130 "/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev",
131 options.msedge && options.unstable,
132 ),
133 (
134 "/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary",
135 options.msedge && options.unstable,
136 ),
137 ];
138
139 for (path, allowed) in default_paths {
140 if !allowed {
141 continue;
142 }
143 if Path::new(path).exists() {
144 return Some(path.into());
145 }
146 }
147
148 None
149}
150
151#[cfg(windows)]
152fn get_by_registry() -> Option<PathBuf> {
153 winreg::RegKey::predef(winreg::enums::HKEY_LOCAL_MACHINE)
154 .open_subkey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe")
155 .or_else(|_| {
156 winreg::RegKey::predef(winreg::enums::HKEY_CURRENT_USER)
157 .open_subkey("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe")
158 })
159 .and_then(|key| key.get_value::<String, _>(""))
160 .map(PathBuf::from)
161 .ok()
162}