Compare commits

..
Author SHA1 Message Date
zhom 615d7b8c8a build: fix windows build warnings 2025-06-09 18:56:38 +04:00
zhom 5c26ab5c33 build: windows build invalid lifetime fix 2025-06-09 18:02:48 +04:00
zhom dccaf6c7de build: blind windows ci build fixes 2025-06-09 15:20:06 +04:00
zhom bf5b2886f5 build: blind windows ci build fixes 2025-06-09 15:01:10 +04:00
4 changed files with 110 additions and 113 deletions
+4 -4
View File
@@ -642,12 +642,12 @@ mod windows {
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// On Windows, TOR and Mullvad browsers can sometimes accept URLs via command line // On Windows, TOR and Mullvad browsers can sometimes accept URLs via command line
// even with -no-remote, by launching a new instance that hands off to existing one // even with -no-remote, by launching a new instance that hands off to existing one
let browser = create_browser(browser_type); let browser = create_browser(browser_type.clone());
let executable_path = browser let executable_path = browser
.get_executable_path(browser_dir) .get_executable_path(browser_dir)
.map_err(|e| format!("Failed to get executable path: {}", e))?; .map_err(|e| format!("Failed to get executable path: {}", e))?;
let mut cmd = Command::new(executable_path); let mut cmd = Command::new(&executable_path);
cmd.args(["-profile", &profile.profile_path, url]); cmd.args(["-profile", &profile.profile_path, url]);
// Set working directory // Set working directory
@@ -685,7 +685,7 @@ mod windows {
.get_executable_path(browser_dir) .get_executable_path(browser_dir)
.map_err(|e| format!("Failed to get executable path: {}", e))?; .map_err(|e| format!("Failed to get executable path: {}", e))?;
let mut cmd = Command::new(executable_path); let mut cmd = Command::new(&executable_path);
cmd.args([ cmd.args([
&format!("--user-data-dir={}", profile.profile_path), &format!("--user-data-dir={}", profile.profile_path),
"--new-window", "--new-window",
@@ -704,7 +704,7 @@ mod windows {
if !output.status.success() { if !output.status.success() {
// Try fallback without --new-window // Try fallback without --new-window
let mut fallback_cmd = Command::new(executable_path); let mut fallback_cmd = Command::new(&executable_path);
fallback_cmd.args([&format!("--user-data-dir={}", profile.profile_path), url]); fallback_cmd.args([&format!("--user-data-dir={}", profile.profile_path), url]);
if let Some(parent_dir) = browser_dir if let Some(parent_dir) = browser_dir
+1 -2
View File
@@ -70,7 +70,6 @@ mod windows {
use winreg::RegKey; use winreg::RegKey;
const APP_NAME: &str = "DonutBrowser"; const APP_NAME: &str = "DonutBrowser";
const APP_EXECUTABLE: &str = "DonutBrowser.exe";
const PROG_ID: &str = "DonutBrowser.HTML"; const PROG_ID: &str = "DonutBrowser.HTML";
pub fn is_default_browser() -> Result<bool, String> { pub fn is_default_browser() -> Result<bool, String> {
@@ -279,7 +278,7 @@ mod windows {
Ok(()) Ok(())
} }
fn register_html_file_association(exe_path: &str) -> Result<(), String> { fn register_html_file_association(_exe_path: &str) -> Result<(), String> {
let hkcu = RegKey::predef(HKEY_CURRENT_USER); let hkcu = RegKey::predef(HKEY_CURRENT_USER);
// Register .html and .htm file associations // Register .html and .htm file associations
+64 -56
View File
@@ -1018,78 +1018,86 @@ impl Extractor {
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
async fn find_windows_executable_recursive( fn find_windows_executable_recursive<'a>(
&self, &'a self,
dir: &Path, dir: &'a Path,
depth: usize, depth: usize,
max_depth: usize, max_depth: usize,
) -> Result<PathBuf, Box<dyn std::error::Error + Send + Sync>> { ) -> std::pin::Pin<
if depth > max_depth { Box<
return Err("Maximum search depth reached".into()); dyn std::future::Future<Output = Result<PathBuf, Box<dyn std::error::Error + Send + Sync>>>
} + Send
+ 'a,
if let Ok(entries) = fs::read_dir(dir) { >,
let mut dirs_to_search = Vec::new(); > {
Box::pin(async move {
// First pass: look for .exe files in current directory if depth > max_depth {
for entry in entries.flatten() { return Err("Maximum search depth reached".into());
let path = entry.path();
if path.is_file()
&& path
.extension()
.is_some_and(|ext| ext.to_string_lossy().to_lowercase() == "exe")
{
let file_name = path
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("")
.to_lowercase();
// Check if it's a browser executable
if file_name.contains("firefox")
|| file_name.contains("chrome")
|| file_name.contains("chromium")
|| file_name.contains("zen")
|| file_name.contains("brave")
|| file_name.contains("tor")
|| file_name.contains("mullvad")
|| file_name.contains("browser")
{
return Ok(path);
}
} else if path.is_dir() {
// Collect directories for later search
dirs_to_search.push(path);
}
} }
// Second pass: search subdirectories
for subdir in dirs_to_search {
if let Ok(result) = self
.find_windows_executable_recursive(&subdir, depth + 1, max_depth)
.await
{
return Ok(result);
}
}
// Third pass: if no browser-specific executable found, return any .exe
if let Ok(entries) = fs::read_dir(dir) { if let Ok(entries) = fs::read_dir(dir) {
let mut dirs_to_search = Vec::new();
// First pass: look for .exe files in current directory
for entry in entries.flatten() { for entry in entries.flatten() {
let path = entry.path(); let path = entry.path();
if path.is_file() if path.is_file()
&& path && path
.extension() .extension()
.is_some_and(|ext| ext.to_string_lossy().to_lowercase() == "exe") .is_some_and(|ext| ext.to_string_lossy().to_lowercase() == "exe")
{ {
return Ok(path); let file_name = path
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("")
.to_lowercase();
// Check if it's a browser executable
if file_name.contains("firefox")
|| file_name.contains("chrome")
|| file_name.contains("chromium")
|| file_name.contains("zen")
|| file_name.contains("brave")
|| file_name.contains("tor")
|| file_name.contains("mullvad")
|| file_name.contains("browser")
{
return Ok(path);
}
} else if path.is_dir() {
// Collect directories for later search
dirs_to_search.push(path);
}
}
// Second pass: search subdirectories
for subdir in dirs_to_search {
if let Ok(result) = self
.find_windows_executable_recursive(&subdir, depth + 1, max_depth)
.await
{
return Ok(result);
}
}
// Third pass: if no browser-specific executable found, return any .exe
if let Ok(entries) = fs::read_dir(dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.is_file()
&& path
.extension()
.is_some_and(|ext| ext.to_string_lossy().to_lowercase() == "exe")
{
return Ok(path);
}
} }
} }
} }
}
Err("No executable found".into()) Err("No executable found".into())
})
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
+41 -51
View File
@@ -84,17 +84,15 @@ impl ProfileImporter {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
// Primary location in AppData\Roaming // Primary location in AppData\Roaming
if let Some(app_data) = self.base_dirs.data_dir() { let app_data = self.base_dirs.data_dir();
let firefox_dir = app_data.join("Mozilla/Firefox/Profiles"); let firefox_dir = app_data.join("Mozilla/Firefox/Profiles");
profiles.extend(self.scan_firefox_profiles_dir(&firefox_dir, "firefox")?); profiles.extend(self.scan_firefox_profiles_dir(&firefox_dir, "firefox")?);
}
// Also check AppData\Local for portable installations // Also check AppData\Local for portable installations
if let Some(local_app_data) = self.base_dirs.data_local_dir() { let local_app_data = self.base_dirs.data_local_dir();
let firefox_local_dir = local_app_data.join("Mozilla/Firefox/Profiles"); let firefox_local_dir = local_app_data.join("Mozilla/Firefox/Profiles");
if firefox_local_dir.exists() { if firefox_local_dir.exists() {
profiles.extend(self.scan_firefox_profiles_dir(&firefox_local_dir, "firefox")?); profiles.extend(self.scan_firefox_profiles_dir(&firefox_local_dir, "firefox")?);
}
} }
} }
@@ -129,12 +127,11 @@ impl ProfileImporter {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
if let Some(app_data) = self.base_dirs.data_dir() { let app_data = self.base_dirs.data_dir();
// Firefox Developer Edition on Windows typically uses separate directories // Firefox Developer Edition on Windows typically uses separate directories
let firefox_dev_dir = app_data.join("Mozilla/Firefox Developer Edition/Profiles"); let firefox_dev_dir = app_data.join("Mozilla/Firefox Developer Edition/Profiles");
if firefox_dev_dir.exists() { if firefox_dev_dir.exists() {
profiles.extend(self.scan_firefox_profiles_dir(&firefox_dev_dir, "firefox-developer")?); profiles.extend(self.scan_firefox_profiles_dir(&firefox_dev_dir, "firefox-developer")?);
}
} }
} }
@@ -168,10 +165,9 @@ impl ProfileImporter {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
if let Some(local_app_data) = self.base_dirs.data_local_dir() { let local_app_data = self.base_dirs.data_local_dir();
let chrome_dir = local_app_data.join("Google/Chrome/User Data"); let chrome_dir = local_app_data.join("Google/Chrome/User Data");
profiles.extend(self.scan_chrome_profiles_dir(&chrome_dir, "chromium")?); profiles.extend(self.scan_chrome_profiles_dir(&chrome_dir, "chromium")?);
}
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
@@ -198,10 +194,9 @@ impl ProfileImporter {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
if let Some(local_app_data) = self.base_dirs.data_local_dir() { let local_app_data = self.base_dirs.data_local_dir();
let chromium_dir = local_app_data.join("Chromium/User Data"); let chromium_dir = local_app_data.join("Chromium/User Data");
profiles.extend(self.scan_chrome_profiles_dir(&chromium_dir, "chromium")?); profiles.extend(self.scan_chrome_profiles_dir(&chromium_dir, "chromium")?);
}
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
@@ -228,10 +223,9 @@ impl ProfileImporter {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
if let Some(local_app_data) = self.base_dirs.data_local_dir() { let local_app_data = self.base_dirs.data_local_dir();
let brave_dir = local_app_data.join("BraveSoftware/Brave-Browser/User Data"); let brave_dir = local_app_data.join("BraveSoftware/Brave-Browser/User Data");
profiles.extend(self.scan_chrome_profiles_dir(&brave_dir, "brave")?); profiles.extend(self.scan_chrome_profiles_dir(&brave_dir, "brave")?);
}
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
@@ -264,17 +258,15 @@ impl ProfileImporter {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
// Primary location in AppData\Roaming // Primary location in AppData\Roaming
if let Some(app_data) = self.base_dirs.data_dir() { let app_data = self.base_dirs.data_dir();
let mullvad_dir = app_data.join("MullvadBrowser/Profiles"); let mullvad_dir = app_data.join("MullvadBrowser/Profiles");
profiles.extend(self.scan_firefox_profiles_dir(&mullvad_dir, "mullvad-browser")?); profiles.extend(self.scan_firefox_profiles_dir(&mullvad_dir, "mullvad-browser")?);
}
// Also check common installation locations // Also check common installation locations
if let Some(local_app_data) = self.base_dirs.data_local_dir() { let local_app_data = self.base_dirs.data_local_dir();
let mullvad_local_dir = local_app_data.join("MullvadBrowser/Profiles"); let mullvad_local_dir = local_app_data.join("MullvadBrowser/Profiles");
if mullvad_local_dir.exists() { if mullvad_local_dir.exists() {
profiles.extend(self.scan_firefox_profiles_dir(&mullvad_local_dir, "mullvad-browser")?); profiles.extend(self.scan_firefox_profiles_dir(&mullvad_local_dir, "mullvad-browser")?);
}
} }
} }
@@ -304,10 +296,9 @@ impl ProfileImporter {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
if let Some(app_data) = self.base_dirs.data_dir() { let app_data = self.base_dirs.data_dir();
let zen_dir = app_data.join("Zen/Profiles"); let zen_dir = app_data.join("Zen/Profiles");
profiles.extend(self.scan_firefox_profiles_dir(&zen_dir, "zen")?); profiles.extend(self.scan_firefox_profiles_dir(&zen_dir, "zen")?);
}
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
@@ -378,17 +369,16 @@ impl ProfileImporter {
} }
// Also check AppData directories if available // Also check AppData directories if available
if let Some(app_data) = self.base_dirs.data_dir() { let app_data = self.base_dirs.data_dir();
let tor_app_data = let tor_app_data =
app_data.join("TorBrowser/Browser/TorBrowser/Data/Browser/profile.default"); app_data.join("TorBrowser/Browser/TorBrowser/Data/Browser/profile.default");
if tor_app_data.exists() { if tor_app_data.exists() {
profiles.push(DetectedProfile { profiles.push(DetectedProfile {
browser: "tor-browser".to_string(), browser: "tor-browser".to_string(),
name: "TOR Browser - AppData Profile".to_string(), name: "TOR Browser - AppData Profile".to_string(),
path: tor_app_data.to_string_lossy().to_string(), path: tor_app_data.to_string_lossy().to_string(),
description: "TOR Browser profile from AppData".to_string(), description: "TOR Browser profile from AppData".to_string(),
}); });
}
} }
} }