windows: Implement AutoUpdater (#25734)

Part of #24800



https://github.com/user-attachments/assets/e70d594e-3635-4f93-9073-5abf7e9d2b20



Release Notes:

- N/A
This commit is contained in:
张小白 2025-04-15 01:36:31 +08:00 committed by GitHub
parent 584fa3db53
commit 1d9915f88a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 721 additions and 37 deletions

View file

@ -168,6 +168,16 @@ fn fail_to_open_window(e: anyhow::Error, _cx: &mut App) {
}
fn main() {
// Check if there is a pending installer
// If there is, run the installer and exit
// And we don't want to run the installer if we are not the first instance
#[cfg(target_os = "windows")]
let is_first_instance = crate::zed::windows_only_instance::is_first_instance();
#[cfg(target_os = "windows")]
if is_first_instance && auto_update::check_pending_installation() {
return;
}
let args = Args::parse();
// Set custom data directory.
@ -236,27 +246,30 @@ fn main() {
let (open_listener, mut open_rx) = OpenListener::new();
let failed_single_instance_check = if *db::ZED_STATELESS
|| *release_channel::RELEASE_CHANNEL == ReleaseChannel::Dev
{
false
} else {
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
{
crate::zed::listen_for_cli_connections(open_listener.clone()).is_err()
}
let failed_single_instance_check =
if *db::ZED_STATELESS || *release_channel::RELEASE_CHANNEL == ReleaseChannel::Dev {
false
} else {
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
{
crate::zed::listen_for_cli_connections(open_listener.clone()).is_err()
}
#[cfg(target_os = "windows")]
{
!crate::zed::windows_only_instance::check_single_instance(open_listener.clone(), &args)
}
#[cfg(target_os = "windows")]
{
!crate::zed::windows_only_instance::handle_single_instance(
open_listener.clone(),
&args,
is_first_instance,
)
}
#[cfg(target_os = "macos")]
{
use zed::mac_only_instance::*;
ensure_only_instance() != IsOnlyInstance::Yes
}
};
#[cfg(target_os = "macos")]
{
use zed::mac_only_instance::*;
ensure_only_instance() != IsOnlyInstance::Yes
}
};
if failed_single_instance_check {
println!("zed is already running");
return;

View file

@ -25,7 +25,7 @@ use windows::{
use crate::{Args, OpenListener};
pub fn check_single_instance(opener: OpenListener, args: &Args) -> bool {
pub fn is_first_instance() -> bool {
unsafe {
CreateMutexW(
None,
@ -34,9 +34,11 @@ pub fn check_single_instance(opener: OpenListener, args: &Args) -> bool {
)
.expect("Unable to create instance mutex.")
};
let first_instance = unsafe { GetLastError() } != ERROR_ALREADY_EXISTS;
unsafe { GetLastError() != ERROR_ALREADY_EXISTS }
}
if first_instance {
pub fn handle_single_instance(opener: OpenListener, args: &Args, is_first_instance: bool) -> bool {
if is_first_instance {
// We are the first instance, listen for messages sent from other instances
std::thread::spawn(move || with_pipe(|url| opener.open_urls(vec![url])));
} else if !args.foreground {
@ -44,7 +46,7 @@ pub fn check_single_instance(opener: OpenListener, args: &Args) -> bool {
send_args_to_instance(args).log_err();
}
first_instance
is_first_instance
}
fn with_pipe(f: impl Fn(String)) {