fix: Single-Instance per User (Terminalserver-kompatibel)
Lock-File liegt in %APPDATA% (Windows) bzw ~/.config (Linux) - das ist pro User verschieden. Auf Terminalservern kann jeder User seine eigene Instanz haben. Verbesserungen: - Prueft ob der Prozess aus dem Lock-File noch lebt (PID-Check) statt nur ob die Datei existiert - Windows: tasklist /FI "PID eq X" - Linux: /proc/PID existiert? - Stale Lock-Files (Prozess abgestuerzt) werden ueberschrieben - Ohne .cloud Argument + andere Instanz laeuft -> sofort beenden - Mit .cloud Argument + andere Instanz -> delegieren und beenden Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -526,6 +526,8 @@ fn start_background_sync(
|
|||||||
// --- App Setup ---
|
// --- App Setup ---
|
||||||
|
|
||||||
/// Check if another instance is running. If yes, pass the .cloud file to it and exit.
|
/// Check if another instance is running. If yes, pass the .cloud file to it and exit.
|
||||||
|
/// Single instance per user. On terminal servers each user gets their own
|
||||||
|
/// instance because the lock file is in %APPDATA% (user-specific).
|
||||||
fn handle_single_instance() {
|
fn handle_single_instance() {
|
||||||
let config_dir = dirs::config_dir()
|
let config_dir = dirs::config_dir()
|
||||||
.unwrap_or_else(|| PathBuf::from("."))
|
.unwrap_or_else(|| PathBuf::from("."))
|
||||||
@@ -535,22 +537,48 @@ fn handle_single_instance() {
|
|||||||
let lock_file = config_dir.join("instance.lock");
|
let lock_file = config_dir.join("instance.lock");
|
||||||
let args: Vec<String> = std::env::args().collect();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
|
|
||||||
// If we have a .cloud file argument and another instance is running
|
// Check if another instance of THIS USER is running
|
||||||
if args.len() > 1 && args[1].ends_with(".cloud") {
|
let other_running = if lock_file.exists() {
|
||||||
if lock_file.exists() {
|
if let Ok(pid_str) = std::fs::read_to_string(&lock_file) {
|
||||||
// Write the .cloud path to a request file for the running instance
|
let pid = pid_str.trim().parse::<u32>().unwrap_or(0);
|
||||||
let request_file = config_dir.join("open_request.txt");
|
if pid > 0 && pid != std::process::id() {
|
||||||
std::fs::write(&request_file, &args[1]).ok();
|
// Check if that process is still alive
|
||||||
eprintln!("[SingleInstance] Passing {} to running instance", args[1]);
|
#[cfg(target_os = "windows")]
|
||||||
std::process::exit(0);
|
{
|
||||||
}
|
std::process::Command::new("tasklist")
|
||||||
|
.args(["/FI", &format!("PID eq {}", pid), "/NH"])
|
||||||
|
.output()
|
||||||
|
.map(|o| String::from_utf8_lossy(&o.stdout).contains(&pid.to_string()))
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
{
|
||||||
|
std::path::Path::new(&format!("/proc/{}", pid)).exists()
|
||||||
|
}
|
||||||
|
} else { false }
|
||||||
|
} else { false }
|
||||||
|
} else { false };
|
||||||
|
|
||||||
|
// If .cloud file argument and another instance runs -> delegate and exit
|
||||||
|
if args.len() > 1 && args[1].ends_with(".cloud") && other_running {
|
||||||
|
let request_file = config_dir.join("open_request.txt");
|
||||||
|
std::fs::write(&request_file, &args[1]).ok();
|
||||||
|
eprintln!("[SingleInstance] Delegated {} to running instance (PID in lock)", args[1]);
|
||||||
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write our lock file
|
// If no .cloud argument but another instance runs -> just bring it to front and exit
|
||||||
std::fs::write(&lock_file, std::process::id().to_string()).ok();
|
if other_running && args.len() <= 1 {
|
||||||
|
eprintln!("[SingleInstance] Already running, exiting");
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are the main instance - write our PID
|
||||||
|
std::fs::write(&lock_file, std::process::id().to_string()).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
handle_single_instance();
|
handle_single_instance();
|
||||||
|
|||||||
Reference in New Issue
Block a user