fix: Update Cargo.toml dependencies on Windows & fix Ctrl+C handling on Windows

This change updates the dependencies of the Cargo.toml file on Windows to include additional features from the `windows-sys` crate. The `CreateProcess flags like CREATE_NEW_PROCESS_GROUP` feature is now enabled to allow for proper process management.
The code now properly sends Ctrl+C to the llama process on Windows, and also includes error handling for when the Ctrl+C command fails. Additionally, it now uses the `Windows` API to kill the process when it times out, and properly handles the wait for the process to exit.
This commit is contained in:
Akarshan 2025-07-03 13:50:19 +05:30
parent c34291237f
commit 6ab7d37a08
No known key found for this signature in database
GPG Key ID: D75C9634A870665F
2 changed files with 26 additions and 10 deletions

View File

@ -62,7 +62,11 @@ nix = "=0.30.1"
[target.'cfg(windows)'.dependencies]
libc = "0.2.172"
windows-sys = "0.60.2"
windows-sys = { version = "0.60.2", features = [
"Win32_Foundation",
"Win32_System_Console",
"Win32_System_Threading" # for using CreateProcess flags like CREATE_NEW_PROCESS_GROUP
] }
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-updater = "2"

View File

@ -3,13 +3,13 @@ use hmac::{Hmac, Mac};
use serde::{Deserialize, Serialize};
use sha2::Sha256;
use std::path::PathBuf;
use std::time::Duration;
use sysinfo::{Pid, ProcessesToUpdate, System};
use tauri::State; // Import Manager trait
use thiserror;
use tokio::process::Command;
use uuid::Uuid;
use std::time::Duration;
use tokio::time::timeout;
use sysinfo::{Pid, ProcessesToUpdate, System};
use uuid::Uuid;
use crate::core::state::AppState;
@ -136,6 +136,8 @@ pub async fn load_llama_model(
// command.stderr(Stdio::piped());
#[cfg(all(windows, target_arch = "x86_64"))]
{
use std::os::windows::process::CommandExt;
const CREATE_NEW_PROCESS_GROUP: u32 = 0x0000_0200;
command.creation_flags(CREATE_NEW_PROCESS_GROUP);
}
@ -199,12 +201,14 @@ pub async fn unload_llama_model(
#[cfg(all(windows, target_arch = "x86_64"))]
{
use windows_sys::Win32::System::Console::{GenerateConsoleCtrlEvent, CTRL_C_EVENT};
use windows_sys::Win32::Foundation::BOOL;
use windows_sys::Win32::System::Console::{GenerateConsoleCtrlEvent, CTRL_C_EVENT};
if let Some(raw_pid) = child.id() {
log::info!("Sending Ctrl-C to PID {}", raw_pid);
let ok: BOOL = unsafe { GenerateConsoleCtrlEvent(CTRL_C_EVENT, raw_pid) };
let ok: BOOL = unsafe {
GenerateConsoleCtrlEvent(CTRL_C_EVENT, raw_pid as u32)
};
if ok == 0 {
log::error!("Failed to send Ctrl-C to PID {}", raw_pid);
}
@ -216,7 +220,10 @@ pub async fn unload_llama_model(
log::warn!("Timed out; force-killing PID {}", raw_pid);
if let Err(e) = child.kill().await {
log::error!("Failed to kill process {}: {}", raw_pid, e);
return Ok(UnloadResult { success: false, error: Some(format!("kill failed: {}", e)) });
return Ok(UnloadResult {
success: false,
error: Some(format!("kill failed: {}", e)),
});
}
if let Ok(s) = child.wait().await {
log::info!("Process finally exited: {}", s);
@ -226,14 +233,19 @@ pub async fn unload_llama_model(
}
}
Ok(UnloadResult { success: true, error: None })
Ok(UnloadResult {
success: true,
error: None,
})
} else {
log::warn!("No server with PID '{}' found", pid);
Ok(UnloadResult { success: true, error: None })
Ok(UnloadResult {
success: true,
error: None,
})
}
}
// crypto
#[tauri::command]
pub fn generate_api_key(model_id: String, api_secret: String) -> Result<String, String> {