diff --git a/qt/launcher/src/main.rs b/qt/launcher/src/main.rs index bd2b02c17..5cc06308c 100644 --- a/qt/launcher/src/main.rs +++ b/qt/launcher/src/main.rs @@ -30,7 +30,7 @@ use crate::platform::get_exe_and_resources_dirs; use crate::platform::get_uv_binary_name; use crate::platform::launch_anki_normally; use crate::platform::respawn_launcher; -use crate::platform::run_anki_normally; +use crate::platform::run_anki_embeddedly; mod platform; @@ -161,7 +161,7 @@ fn run() -> Result<()> { if !launcher_requested && !pyproject_has_changed && !different_launcher { // If no launcher request and venv is already up to date, launch Anki normally - if std::env::var("ANKI_LAUNCHER_NO_EMBED").is_ok() || !run_anki_normally(&state) { + if std::env::var("ANKI_LAUNCHER_NO_EMBED").is_ok() || !run_anki_embeddedly(&state) { let args: Vec = std::env::args().skip(1).collect(); let cmd = build_python_command(&state, &args)?; launch_anki_normally(cmd)?; diff --git a/qt/launcher/src/platform/mod.rs b/qt/launcher/src/platform/mod.rs index e6c7efd37..ac959a075 100644 --- a/qt/launcher/src/platform/mod.rs +++ b/qt/launcher/src/platform/mod.rs @@ -20,6 +20,7 @@ use std::ffi::CStr; use std::ffi::CString; use std::path::PathBuf; +use anki_io::ToUtf8Path; use anki_process::CommandExt; use anyhow::anyhow; use anyhow::ensure; @@ -119,7 +120,16 @@ pub fn launch_anki_normally(mut cmd: std::process::Command) -> Result<()> { Ok(()) } -pub fn _run_anki_normally(state: &crate::State) -> Result<()> { +pub fn _run_anki_embeddedly(state: &crate::State) -> Result<()> { + let (version, lib_path, exec) = crate::get_python_env_info(state)?; + + std::env::set_var("ANKI_LAUNCHER", std::env::current_exe()?.utf8()?.as_str()); + std::env::set_var("ANKI_LAUNCHER_UV", state.uv_path.utf8()?.as_str()); + std::env::set_var("UV_PROJECT", state.uv_install_root.utf8()?.as_str()); + std::env::remove_var("SSLKEYLOGFILE"); + + let ffi = PyFfi::load(lib_path, exec)?; + #[cfg(windows)] { let console = std::env::var("ANKI_CONSOLE").is_ok(); @@ -128,15 +138,17 @@ pub fn _run_anki_normally(state: &crate::State) -> Result<()> { ensure_terminal_shown()?; } crate::platform::windows::prepare_to_launch_normally(); - windows::run(state, console)?; + // NOTE: without windows_subsystem=console or pythonw, + // we need to reconnect stdin/stdout/stderr within the interp + let preamble = console.then_some(cr#"import sys; sys.stdout = sys.stderr = open("CONOUT$", "w"); sys.stdin = open("CONIN$", "r");"#); + ffi.run(&version, preamble) } #[cfg(unix)] - nix::run(state)?; - Ok(()) + ffi.run(&version, None) } -pub fn run_anki_normally(state: &crate::State) -> bool { - if let Err(e) = _run_anki_normally(state) { +pub fn run_anki_embeddedly(state: &crate::State) -> bool { + if let Err(e) = _run_anki_embeddedly(state) { eprintln!("failed to run as embedded: {e:?}"); return false; } diff --git a/qt/launcher/src/platform/nix.rs b/qt/launcher/src/platform/nix.rs index 823c968c3..f1d769221 100644 --- a/qt/launcher/src/platform/nix.rs +++ b/qt/launcher/src/platform/nix.rs @@ -5,12 +5,9 @@ use std::ffi::CStr; use std::ffi::CString; use std::os::unix::prelude::OsStrExt; -use anki_io::ToUtf8Path; use anyhow::Result; -use crate::get_python_env_info; use crate::platform::PyFfi; -use crate::State; impl Drop for PyFfi { fn drop(&mut self) { @@ -77,14 +74,3 @@ impl PyFfi { } } } - -pub fn run(state: &State) -> Result<()> { - let (version, lib_path, exec) = get_python_env_info(state)?; - - std::env::set_var("ANKI_LAUNCHER", std::env::current_exe()?.utf8()?.as_str()); - std::env::set_var("ANKI_LAUNCHER_UV", state.uv_path.utf8()?.as_str()); - std::env::set_var("UV_PROJECT", state.uv_install_root.utf8()?.as_str()); - std::env::remove_var("SSLKEYLOGFILE"); - - PyFfi::load(lib_path, exec)?.run(&version, None) -} diff --git a/qt/launcher/src/platform/windows.rs b/qt/launcher/src/platform/windows.rs index 2b1836ead..dca8b483e 100644 --- a/qt/launcher/src/platform/windows.rs +++ b/qt/launcher/src/platform/windows.rs @@ -6,7 +6,6 @@ use std::io::stdin; use std::os::windows::ffi::OsStrExt; use std::process::Command; -use anki_io::ToUtf8Path; use anyhow::anyhow; use anyhow::Context; use anyhow::Result; @@ -30,9 +29,7 @@ use windows::Win32::System::Registry::REG_SZ; use windows::Win32::System::SystemInformation::OSVERSIONINFOW; use windows::Win32::UI::Shell::SetCurrentProcessExplicitAppUserModelID; -use crate::get_python_env_info; use crate::platform::PyFfi; -use crate::State; /// Returns true if running on Windows 10 (not Windows 11) fn is_windows_10() -> bool { @@ -334,21 +331,3 @@ impl PyFfi { } } } - -pub fn run(state: &State, console: bool) -> Result<()> { - let (version, lib_path, exec) = get_python_env_info(state)?; - - std::env::set_var("ANKI_LAUNCHER", std::env::current_exe()?.utf8()?.as_str()); - std::env::set_var("ANKI_LAUNCHER_UV", state.uv_path.utf8()?.as_str()); - std::env::set_var("UV_PROJECT", state.uv_install_root.utf8()?.as_str()); - std::env::remove_var("SSLKEYLOGFILE"); - - // NOTE: without windows_subsystem=console or pythonw, - // we need to reconnect stdin/stdout/stderr within the interp - // reconnect_stdio_to_console doesn't make a difference here - let preamble = console.then_some( - cr#"import sys; sys.stdout = sys.stderr = open("CONOUT$", "w"); sys.stdin = open("CONIN$", "r");"#, - ); - - PyFfi::load(lib_path, exec)?.run(&version, preamble) -}