Switch to the windows crate

This commit is contained in:
Damien Elmes 2025-06-29 16:49:20 +07:00
parent 349a696f93
commit 6eb1db0f5d
4 changed files with 40 additions and 33 deletions

2
Cargo.lock generated
View file

@ -3548,7 +3548,7 @@ dependencies = [
"embed-resource",
"libc",
"libc-stdhandle",
"winapi",
"windows 0.61.3",
]
[[package]]

View file

@ -139,7 +139,7 @@ unicode-normalization = "0.1.24"
walkdir = "2.5.0"
which = "8.0.0"
winapi = { version = "0.3", features = ["wincon", "winreg"] }
windows = { version = "0.61.3", features = ["Media_SpeechSynthesis", "Media_Core", "Foundation_Collections", "Storage_Streams"] }
windows = { version = "0.61.3", features = ["Media_SpeechSynthesis", "Media_Core", "Foundation_Collections", "Storage_Streams", "Win32_System_Console", "Win32_System_Registry", "Win32_Foundation"] }
wiremock = "0.6.3"
xz2 = "0.1.7"
zip = { version = "4.1.0", default-features = false, features = ["deflate", "time"] }

View file

@ -15,7 +15,7 @@ camino.workspace = true
dirs.workspace = true
[target.'cfg(windows)'.dependencies]
winapi.workspace = true
windows.workspace = true
libc.workspace = true
libc-stdhandle.workspace = true

View file

@ -8,14 +8,21 @@ use std::process::Command;
use anyhow::Context;
use anyhow::Result;
use winapi::shared::minwindef::HKEY;
use winapi::um::wincon;
use winapi::um::winnt::KEY_READ;
use winapi::um::winreg;
use windows::core::PCWSTR;
use windows::Win32::System::Registry::HKEY_CURRENT_USER;
use windows::Win32::System::Console::AttachConsole;
use windows::Win32::System::Console::GetConsoleWindow;
use windows::Win32::System::Console::ATTACH_PARENT_PROCESS;
use windows::Win32::System::Registry::RegCloseKey;
use windows::Win32::System::Registry::RegOpenKeyExW;
use windows::Win32::System::Registry::RegQueryValueExW;
use windows::Win32::System::Registry::HKEY;
use windows::Win32::System::Registry::KEY_READ;
use windows::Win32::System::Registry::REG_SZ;
pub fn ensure_terminal_shown() -> Result<()> {
unsafe {
if !wincon::GetConsoleWindow().is_null() {
if !GetConsoleWindow().is_invalid() {
// We already have a console, no need to spawn anki-console.exe
return Ok(());
}
@ -51,12 +58,12 @@ pub fn ensure_terminal_shown() -> Result<()> {
pub fn attach_to_parent_console() -> bool {
unsafe {
if !wincon::GetConsoleWindow().is_null() {
if !GetConsoleWindow().is_invalid() {
// we have a console already
return false;
}
if wincon::AttachConsole(wincon::ATTACH_PARENT_PROCESS) != 0 {
if AttachConsole(ATTACH_PARENT_PROCESS).is_ok() {
// successfully attached to parent
reconnect_stdio_to_console();
true
@ -136,7 +143,7 @@ fn get_uninstaller_path() -> Option<std::path::PathBuf> {
fn read_registry_install_dir() -> Option<std::path::PathBuf> {
unsafe {
let mut hkey: HKEY = std::ptr::null_mut();
let mut hkey = HKEY::default();
// Convert the registry path to wide string
let subkey: Vec<u16> = OsStr::new("SOFTWARE\\Anki")
@ -145,15 +152,15 @@ fn read_registry_install_dir() -> Option<std::path::PathBuf> {
.collect();
// Open the registry key
let result = winreg::RegOpenKeyExW(
winreg::HKEY_CURRENT_USER,
subkey.as_ptr(),
0,
let result = RegOpenKeyExW(
HKEY_CURRENT_USER,
PCWSTR(subkey.as_ptr()),
Some(0),
KEY_READ,
&mut hkey,
);
if result != 0 {
if result.is_err() {
return None;
}
@ -163,38 +170,38 @@ fn read_registry_install_dir() -> Option<std::path::PathBuf> {
.chain(std::iter::once(0))
.collect();
let mut value_type = 0u32;
let mut value_type = REG_SZ;
let mut data_size = 0u32;
// First call to get the size
let result = winreg::RegQueryValueExW(
let result = RegQueryValueExW(
hkey,
value_name.as_ptr(),
std::ptr::null_mut(),
&mut value_type,
std::ptr::null_mut(),
&mut data_size,
PCWSTR(value_name.as_ptr()),
None,
Some(&mut value_type),
None,
Some(&mut data_size),
);
if result != 0 || data_size == 0 {
winreg::RegCloseKey(hkey);
if result.is_err() || data_size == 0 {
let _ = RegCloseKey(hkey);
return None;
}
// Allocate buffer and read the value
let mut buffer: Vec<u16> = vec![0; (data_size / 2) as usize];
let result = winreg::RegQueryValueExW(
let result = RegQueryValueExW(
hkey,
value_name.as_ptr(),
std::ptr::null_mut(),
&mut value_type,
buffer.as_mut_ptr() as *mut u8,
&mut data_size,
PCWSTR(value_name.as_ptr()),
None,
Some(&mut value_type),
Some(buffer.as_mut_ptr() as *mut u8),
Some(&mut data_size),
);
winreg::RegCloseKey(hkey);
let _ = RegCloseKey(hkey);
if result == 0 {
if result.is_ok() {
// Convert wide string back to PathBuf
let len = buffer.iter().position(|&x| x == 0).unwrap_or(buffer.len());
let path_str = String::from_utf16_lossy(&buffer[..len]);