mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-06 08:32:51 +08:00
🌱 尝试检测管理员&以管理员模式重启
This commit is contained in:
@@ -36,14 +36,14 @@ walkdir = "2.5.0"
|
||||
[target.'cfg(windows)'.dependencies.windows-sys]
|
||||
version = "0.61.2"
|
||||
features = [
|
||||
"Win32_System_Diagnostics_ToolHelp",
|
||||
"Win32_System_WindowsProgramming",
|
||||
"Win32_System_Pipes",
|
||||
"Win32_System_Memory",
|
||||
"Win32_System_Diagnostics",
|
||||
"Win32_System_Diagnostics_Debug",
|
||||
"Win32_System_Diagnostics_ToolHelp",
|
||||
"Win32_System_LibraryLoader",
|
||||
"Win32_System_Memory",
|
||||
"Win32_System_Pipes",
|
||||
"Win32_System_Threading",
|
||||
"Win32_System_WindowsProgramming",
|
||||
]
|
||||
|
||||
# deep link 插件
|
||||
|
||||
@@ -70,3 +70,81 @@ pub async fn get_dir_size(path: String) -> u64 {
|
||||
}
|
||||
size
|
||||
}
|
||||
|
||||
// 判断是否是管理员权限
|
||||
#[cfg(target_os = "windows")]
|
||||
#[tauri::command]
|
||||
pub fn is_in_admin() -> bool {
|
||||
use windows_sys::Win32::Foundation::HANDLE;
|
||||
use windows_sys::Win32::Security::{
|
||||
AllocateAndInitializeSid, CheckTokenMembership, FreeSid, SID_IDENTIFIER_AUTHORITY, TOKEN_QUERY,
|
||||
};
|
||||
use windows_sys::Win32::System::SystemServices::{
|
||||
DOMAIN_ALIAS_RID_ADMINS, SECURITY_BUILTIN_DOMAIN_RID,
|
||||
};
|
||||
use windows_sys::Win32::System::Threading::{GetCurrentProcess, OpenProcessToken};
|
||||
|
||||
unsafe {
|
||||
let mut token_handle: HANDLE = std::ptr::null_mut();
|
||||
if OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut token_handle) != 0 {
|
||||
let nt_authority = SID_IDENTIFIER_AUTHORITY { Value: [0, 0, 0, 0, 0, 5] };
|
||||
let mut admin_group = std::ptr::null_mut();
|
||||
if AllocateAndInitializeSid(
|
||||
&nt_authority,
|
||||
2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID.try_into().unwrap(),
|
||||
DOMAIN_ALIAS_RID_ADMINS.try_into().unwrap(),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut admin_group,
|
||||
) != 0
|
||||
{
|
||||
let mut is_admin = 0i32;
|
||||
CheckTokenMembership(std::ptr::null_mut(), admin_group, &mut is_admin);
|
||||
FreeSid(admin_group);
|
||||
return is_admin != 0;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// 在 Windows 上以管理员权限重启应用
|
||||
#[cfg(target_os = "windows")]
|
||||
#[tauri::command]
|
||||
pub fn run_with_admin() -> Result<(), String> {
|
||||
use std::ffi::OsStr;
|
||||
use std::iter::once;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::process::exit;
|
||||
use windows_sys::Win32::UI::Shell::ShellExecuteW;
|
||||
use windows_sys::Win32::UI::WindowsAndMessaging::SW_SHOWNORMAL;
|
||||
|
||||
let exe_path = std::env::current_exe().map_err(|e| e.to_string())?;
|
||||
let exe_str: Vec<u16> = OsStr::new(exe_path.to_string_lossy().as_ref())
|
||||
.encode_wide()
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
let verb: Vec<u16> = OsStr::new("runas").encode_wide().chain(once(0)).collect();
|
||||
|
||||
let result = unsafe {
|
||||
ShellExecuteW(
|
||||
std::ptr::null_mut(),
|
||||
verb.as_ptr(),
|
||||
exe_str.as_ptr(),
|
||||
std::ptr::null(),
|
||||
std::ptr::null(),
|
||||
SW_SHOWNORMAL,
|
||||
)
|
||||
};
|
||||
|
||||
if result as usize > 32 {
|
||||
exit(0);
|
||||
} else {
|
||||
Err("Failed to restart as administrator.".into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ mod utils;
|
||||
mod yae;
|
||||
|
||||
use crate::client::create_mhy_client;
|
||||
use crate::commands::{create_window, execute_js, get_dir_size, init_app};
|
||||
use crate::commands::{
|
||||
create_window, execute_js, get_dir_size, init_app, is_in_admin, run_with_admin,
|
||||
};
|
||||
use crate::plugins::{build_log_plugin, build_si_plugin};
|
||||
use crate::yae::call_yae_dll;
|
||||
use tauri::{generate_context, generate_handler, Builder, Manager, Window, WindowEvent};
|
||||
@@ -63,7 +65,9 @@ pub fn run() {
|
||||
execute_js,
|
||||
get_dir_size,
|
||||
create_mhy_client,
|
||||
call_yae_dll
|
||||
call_yae_dll,
|
||||
is_in_admin,
|
||||
run_with_admin
|
||||
])
|
||||
.run(generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@@ -6,17 +6,15 @@ pub mod proto;
|
||||
|
||||
use inject::{call_yaemain, create_named_pipe, find_module_base, inject_dll, spawn_process};
|
||||
use prost::encoding::{decode_key, WireType};
|
||||
use prost::Message;
|
||||
use proto::{parse_achi_list, AchievementInfo};
|
||||
use proto::parse_achi_list;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{Read, Write};
|
||||
use std::os::windows::io::{FromRawHandle, OwnedHandle, RawHandle};
|
||||
use std::os::windows::io::{FromRawHandle, RawHandle};
|
||||
use std::sync::Arc;
|
||||
use tauri::{AppHandle, Emitter, Manager};
|
||||
use windows_sys::Win32::Storage::FileSystem::ReadFile;
|
||||
use windows_sys::Win32::System::Pipes::ConnectNamedPipe;
|
||||
|
||||
// 读取配置值
|
||||
@@ -79,8 +77,6 @@ pub fn parse_achievement_data(bytes: &[u8]) -> Vec<HashMap<u32, u32>> {
|
||||
data
|
||||
}
|
||||
|
||||
use windows_sys::Win32::Foundation::{GetLastError, ERROR_MORE_DATA};
|
||||
|
||||
fn read_u32_le<R: Read>(r: &mut R) -> io::Result<u32> {
|
||||
let mut buf = [0u8; 4];
|
||||
match r.read_exact(&mut buf) {
|
||||
|
||||
@@ -106,15 +106,15 @@ pub struct AchievementInfo {
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
pub struct AchievementEntry {
|
||||
pub struct AchiItemRes {
|
||||
pub id: u32,
|
||||
pub total_progress: u32,
|
||||
pub current_progress: u32,
|
||||
pub finish_timestamp: u32,
|
||||
pub status: u32, // 数值类型
|
||||
pub total: u32,
|
||||
pub cur: u32,
|
||||
pub ts: u32,
|
||||
pub stat: u32,
|
||||
}
|
||||
|
||||
pub fn parse_achi_list(bytes: &[u8]) -> Result<Vec<AchievementEntry>, DecodeError> {
|
||||
pub fn parse_achi_list(bytes: &[u8]) -> Result<Vec<AchiItemRes>, DecodeError> {
|
||||
let mut cursor = Cursor::new(bytes);
|
||||
let mut dicts: Vec<HashMap<u32, u32>> = Vec::new();
|
||||
|
||||
@@ -146,12 +146,12 @@ pub fn parse_achi_list(bytes: &[u8]) -> Result<Vec<AchievementEntry>, DecodeErro
|
||||
|
||||
let achievements = dicts
|
||||
.into_iter()
|
||||
.map(|d| AchievementEntry {
|
||||
.map(|d| AchiItemRes {
|
||||
id: d.get(&15).copied().unwrap_or(0),
|
||||
status: d.get(&11).copied().unwrap_or(0),
|
||||
total_progress: d.get(&8).copied().unwrap_or(0),
|
||||
current_progress: d.get(&13).copied().unwrap_or(0),
|
||||
finish_timestamp: d.get(&7).copied().unwrap_or(0),
|
||||
stat: d.get(&11).copied().unwrap_or(0),
|
||||
total: d.get(&8).copied().unwrap_or(0),
|
||||
cur: d.get(&13).copied().unwrap_or(0),
|
||||
ts: d.get(&7).copied().unwrap_or(0),
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user