dedup platform-specific run

This commit is contained in:
llama 2025-11-23 16:31:18 +08:00
parent dbc7adca2d
commit 7c4a1e6c00
No known key found for this signature in database
GPG key ID: 0B7543854B9413C3
4 changed files with 20 additions and 43 deletions

View file

@ -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<String> = std::env::args().skip(1).collect();
let cmd = build_python_command(&state, &args)?;
launch_anki_normally(cmd)?;

View file

@ -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;
}

View file

@ -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)
}

View file

@ -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)
}