mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Switch to the windows crate
This commit is contained in:
parent
349a696f93
commit
6eb1db0f5d
4 changed files with 40 additions and 33 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -3548,7 +3548,7 @@ dependencies = [
|
||||||
"embed-resource",
|
"embed-resource",
|
||||||
"libc",
|
"libc",
|
||||||
"libc-stdhandle",
|
"libc-stdhandle",
|
||||||
"winapi",
|
"windows 0.61.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -139,7 +139,7 @@ unicode-normalization = "0.1.24"
|
||||||
walkdir = "2.5.0"
|
walkdir = "2.5.0"
|
||||||
which = "8.0.0"
|
which = "8.0.0"
|
||||||
winapi = { version = "0.3", features = ["wincon", "winreg"] }
|
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"
|
wiremock = "0.6.3"
|
||||||
xz2 = "0.1.7"
|
xz2 = "0.1.7"
|
||||||
zip = { version = "4.1.0", default-features = false, features = ["deflate", "time"] }
|
zip = { version = "4.1.0", default-features = false, features = ["deflate", "time"] }
|
||||||
|
|
|
@ -15,7 +15,7 @@ camino.workspace = true
|
||||||
dirs.workspace = true
|
dirs.workspace = true
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi.workspace = true
|
windows.workspace = true
|
||||||
libc.workspace = true
|
libc.workspace = true
|
||||||
libc-stdhandle.workspace = true
|
libc-stdhandle.workspace = true
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,21 @@ use std::process::Command;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use winapi::shared::minwindef::HKEY;
|
use windows::core::PCWSTR;
|
||||||
use winapi::um::wincon;
|
use windows::Win32::System::Registry::HKEY_CURRENT_USER;
|
||||||
use winapi::um::winnt::KEY_READ;
|
use windows::Win32::System::Console::AttachConsole;
|
||||||
use winapi::um::winreg;
|
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<()> {
|
pub fn ensure_terminal_shown() -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !wincon::GetConsoleWindow().is_null() {
|
if !GetConsoleWindow().is_invalid() {
|
||||||
// We already have a console, no need to spawn anki-console.exe
|
// We already have a console, no need to spawn anki-console.exe
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -51,12 +58,12 @@ pub fn ensure_terminal_shown() -> Result<()> {
|
||||||
|
|
||||||
pub fn attach_to_parent_console() -> bool {
|
pub fn attach_to_parent_console() -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !wincon::GetConsoleWindow().is_null() {
|
if !GetConsoleWindow().is_invalid() {
|
||||||
// we have a console already
|
// we have a console already
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if wincon::AttachConsole(wincon::ATTACH_PARENT_PROCESS) != 0 {
|
if AttachConsole(ATTACH_PARENT_PROCESS).is_ok() {
|
||||||
// successfully attached to parent
|
// successfully attached to parent
|
||||||
reconnect_stdio_to_console();
|
reconnect_stdio_to_console();
|
||||||
true
|
true
|
||||||
|
@ -136,7 +143,7 @@ fn get_uninstaller_path() -> Option<std::path::PathBuf> {
|
||||||
|
|
||||||
fn read_registry_install_dir() -> Option<std::path::PathBuf> {
|
fn read_registry_install_dir() -> Option<std::path::PathBuf> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut hkey: HKEY = std::ptr::null_mut();
|
let mut hkey = HKEY::default();
|
||||||
|
|
||||||
// Convert the registry path to wide string
|
// Convert the registry path to wide string
|
||||||
let subkey: Vec<u16> = OsStr::new("SOFTWARE\\Anki")
|
let subkey: Vec<u16> = OsStr::new("SOFTWARE\\Anki")
|
||||||
|
@ -145,15 +152,15 @@ fn read_registry_install_dir() -> Option<std::path::PathBuf> {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Open the registry key
|
// Open the registry key
|
||||||
let result = winreg::RegOpenKeyExW(
|
let result = RegOpenKeyExW(
|
||||||
winreg::HKEY_CURRENT_USER,
|
HKEY_CURRENT_USER,
|
||||||
subkey.as_ptr(),
|
PCWSTR(subkey.as_ptr()),
|
||||||
0,
|
Some(0),
|
||||||
KEY_READ,
|
KEY_READ,
|
||||||
&mut hkey,
|
&mut hkey,
|
||||||
);
|
);
|
||||||
|
|
||||||
if result != 0 {
|
if result.is_err() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,38 +170,38 @@ fn read_registry_install_dir() -> Option<std::path::PathBuf> {
|
||||||
.chain(std::iter::once(0))
|
.chain(std::iter::once(0))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut value_type = 0u32;
|
let mut value_type = REG_SZ;
|
||||||
let mut data_size = 0u32;
|
let mut data_size = 0u32;
|
||||||
|
|
||||||
// First call to get the size
|
// First call to get the size
|
||||||
let result = winreg::RegQueryValueExW(
|
let result = RegQueryValueExW(
|
||||||
hkey,
|
hkey,
|
||||||
value_name.as_ptr(),
|
PCWSTR(value_name.as_ptr()),
|
||||||
std::ptr::null_mut(),
|
None,
|
||||||
&mut value_type,
|
Some(&mut value_type),
|
||||||
std::ptr::null_mut(),
|
None,
|
||||||
&mut data_size,
|
Some(&mut data_size),
|
||||||
);
|
);
|
||||||
|
|
||||||
if result != 0 || data_size == 0 {
|
if result.is_err() || data_size == 0 {
|
||||||
winreg::RegCloseKey(hkey);
|
let _ = RegCloseKey(hkey);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate buffer and read the value
|
// Allocate buffer and read the value
|
||||||
let mut buffer: Vec<u16> = vec![0; (data_size / 2) as usize];
|
let mut buffer: Vec<u16> = vec![0; (data_size / 2) as usize];
|
||||||
let result = winreg::RegQueryValueExW(
|
let result = RegQueryValueExW(
|
||||||
hkey,
|
hkey,
|
||||||
value_name.as_ptr(),
|
PCWSTR(value_name.as_ptr()),
|
||||||
std::ptr::null_mut(),
|
None,
|
||||||
&mut value_type,
|
Some(&mut value_type),
|
||||||
buffer.as_mut_ptr() as *mut u8,
|
Some(buffer.as_mut_ptr() as *mut u8),
|
||||||
&mut data_size,
|
Some(&mut data_size),
|
||||||
);
|
);
|
||||||
|
|
||||||
winreg::RegCloseKey(hkey);
|
let _ = RegCloseKey(hkey);
|
||||||
|
|
||||||
if result == 0 {
|
if result.is_ok() {
|
||||||
// Convert wide string back to PathBuf
|
// Convert wide string back to PathBuf
|
||||||
let len = buffer.iter().position(|&x| x == 0).unwrap_or(buffer.len());
|
let len = buffer.iter().position(|&x| x == 0).unwrap_or(buffer.len());
|
||||||
let path_str = String::from_utf16_lossy(&buffer[..len]);
|
let path_str = String::from_utf16_lossy(&buffer[..len]);
|
||||||
|
|
Loading…
Reference in a new issue