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