mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-05-02 10:16:28 +02:00
fix(terminal): windows&macos, charset utf-8
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -318,6 +318,35 @@ pub fn get_default_shell() -> String {
|
||||
std::env::var("COMSPEC").unwrap_or_else(|_| "cmd.exe".to_string())
|
||||
}
|
||||
|
||||
fn utf8_shell_args(shell: &str) -> Vec<String> {
|
||||
let name = std::path::Path::new(shell)
|
||||
.file_name()
|
||||
.and_then(|name| name.to_str())
|
||||
.unwrap_or(shell)
|
||||
.to_ascii_lowercase();
|
||||
|
||||
if name == "cmd.exe" || name == "cmd" {
|
||||
return vec!["/K".to_string(), "chcp 65001 >NUL".to_string()];
|
||||
}
|
||||
|
||||
if name == "pwsh.exe" || name == "pwsh" || name == "powershell.exe" {
|
||||
return vec![
|
||||
"-NoLogo".to_string(),
|
||||
"-NoExit".to_string(),
|
||||
"-Command".to_string(),
|
||||
"chcp.com 65001 > $null; [Console]::InputEncoding = [System.Text.Encoding]::UTF8; [Console]::OutputEncoding = [System.Text.Encoding]::UTF8".to_string(),
|
||||
];
|
||||
}
|
||||
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
pub fn configure_utf8_shell_command(shell: &str, cmd: &mut CommandBuilder) {
|
||||
for arg in utf8_shell_args(shell) {
|
||||
cmd.arg(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the SID of the user from a token.
|
||||
/// Returns a Vec<u8> containing the SID bytes.
|
||||
pub fn get_user_sid_from_token(user_token: UserToken) -> Result<Vec<u8>> {
|
||||
@@ -831,7 +860,8 @@ pub fn run_terminal_helper(args: &[String]) -> Result<()> {
|
||||
let shell = get_default_shell();
|
||||
log::debug!("Using shell: {}", shell);
|
||||
|
||||
let cmd = CommandBuilder::new(&shell);
|
||||
let mut cmd = CommandBuilder::new(&shell);
|
||||
configure_utf8_shell_command(&shell, &mut cmd);
|
||||
let mut child = pty_pair
|
||||
.slave
|
||||
.spawn_command(cmd)
|
||||
|
||||
@@ -20,10 +20,11 @@ use std::{
|
||||
// Windows-specific imports from terminal_helper module
|
||||
#[cfg(target_os = "windows")]
|
||||
use super::terminal_helper::{
|
||||
create_named_pipe_server, encode_helper_message, encode_resize_message,
|
||||
is_helper_process_running, launch_terminal_helper_with_token, wait_for_pipe_connection,
|
||||
HelperProcessGuard, OwnedHandle, SendableHandle, WinCloseHandle, WinTerminateProcess,
|
||||
WinWaitForSingleObject, MSG_TYPE_DATA, PIPE_CONNECTION_TIMEOUT_MS, WIN_WAIT_OBJECT_0,
|
||||
configure_utf8_shell_command, create_named_pipe_server, encode_helper_message,
|
||||
encode_resize_message, is_helper_process_running, launch_terminal_helper_with_token,
|
||||
wait_for_pipe_connection, HelperProcessGuard, OwnedHandle, SendableHandle, WinCloseHandle,
|
||||
WinTerminateProcess, WinWaitForSingleObject, MSG_TYPE_DATA, PIPE_CONNECTION_TIMEOUT_MS,
|
||||
WIN_WAIT_OBJECT_0,
|
||||
};
|
||||
|
||||
const MAX_OUTPUT_BUFFER_SIZE: usize = 1024 * 1024; // 1MB per terminal
|
||||
@@ -133,6 +134,26 @@ fn get_default_shell() -> String {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn locale_value_is_utf8(value: &str) -> bool {
|
||||
let value = value.to_ascii_uppercase();
|
||||
value.contains("UTF-8") || value.contains("UTF8")
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn should_force_process_utf8_ctype() -> bool {
|
||||
if let Ok(value) = std::env::var("LC_ALL") {
|
||||
return !locale_value_is_utf8(&value);
|
||||
}
|
||||
if let Ok(value) = std::env::var("LC_CTYPE") {
|
||||
return !locale_value_is_utf8(&value);
|
||||
}
|
||||
if let Ok(value) = std::env::var("LANG") {
|
||||
return !locale_value_is_utf8(&value);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn is_service_specified_user(service_id: &str) -> Option<bool> {
|
||||
get_service(service_id).map(|s| s.lock().unwrap().is_specified_user)
|
||||
}
|
||||
@@ -1146,6 +1167,9 @@ impl TerminalServiceProxy {
|
||||
#[allow(unused_mut)]
|
||||
let mut cmd = CommandBuilder::new(&shell);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
configure_utf8_shell_command(&shell, &mut cmd);
|
||||
|
||||
// macOS-specific terminal configuration
|
||||
// 1. Use login shell (-l) to load user's shell profile (~/.zprofile, ~/.bash_profile)
|
||||
// This ensures PATH includes Homebrew paths (/opt/homebrew/bin, /usr/local/bin)
|
||||
@@ -1166,6 +1190,12 @@ impl TerminalServiceProxy {
|
||||
};
|
||||
cmd.env("TERM", term);
|
||||
log::debug!("Set TERM={} for macOS PTY", term);
|
||||
|
||||
if should_force_process_utf8_ctype() {
|
||||
cmd.env_remove("LC_ALL");
|
||||
cmd.env("LC_CTYPE", "UTF-8");
|
||||
log::debug!("Set LC_CTYPE=UTF-8 for macOS PTY");
|
||||
}
|
||||
}
|
||||
|
||||
// Note: On Windows with user_token, we use helper mode (handle_open_with_helper)
|
||||
|
||||
Reference in New Issue
Block a user