🐞 fix: cmd error with gbk (#114)

* 🐞 fix: cmd error with gbk
* 🎈 perf: try gbk only on windows
This commit is contained in:
m1m1sha 2024-05-15 20:50:11 +08:00 committed by GitHub
parent d5bf041834
commit 58d2ec475c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 92 additions and 5 deletions

65
Cargo.lock generated
View File

@ -1278,6 +1278,7 @@ dependencies = [
"dashmap", "dashmap",
"defguard_wireguard_rs", "defguard_wireguard_rs",
"derivative", "derivative",
"encoding",
"futures", "futures",
"gethostname", "gethostname",
"http 1.1.0", "http 1.1.0",
@ -1381,6 +1382,70 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
[[package]]
name = "encoding"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
dependencies = [
"encoding-index-japanese",
"encoding-index-korean",
"encoding-index-simpchinese",
"encoding-index-singlebyte",
"encoding-index-tradchinese",
]
[[package]]
name = "encoding-index-japanese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-korean"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-simpchinese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-singlebyte"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-tradchinese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding_index_tests"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
version = "0.8.33" version = "0.8.33"

View File

@ -164,6 +164,7 @@ windows-sys = { version = "0.52", features = [
"Win32_Foundation", "Win32_Foundation",
"Win32_System_IO", "Win32_System_IO",
] } ] }
encoding = "0.2"
[build-dependencies] [build-dependencies]
tonic-build = "0.10" tonic-build = "0.10"

View File

@ -50,6 +50,8 @@ fn cidr_to_subnet_mask(prefix_length: u8) -> Ipv4Addr {
async fn run_shell_cmd(cmd: &str) -> Result<(), Error> { async fn run_shell_cmd(cmd: &str) -> Result<(), Error> {
let cmd_out: std::process::Output; let cmd_out: std::process::Output;
let stdout: String;
let stderr: String;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
const CREATE_NO_WINDOW: u32 = 0x08000000; const CREATE_NO_WINDOW: u32 = 0x08000000;
@ -58,22 +60,25 @@ async fn run_shell_cmd(cmd: &str) -> Result<(), Error> {
.arg(cmd) .arg(cmd)
.creation_flags(CREATE_NO_WINDOW) .creation_flags(CREATE_NO_WINDOW)
.output() .output()
.await? .await?;
stdout = crate::utils::utf8_or_gbk_to_string(cmd_out.stdout.as_slice());
stderr = crate::utils::utf8_or_gbk_to_string(cmd_out.stderr.as_slice());
}; };
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
{ {
cmd_out = Command::new("sh").arg("-c").arg(cmd).output().await? cmd_out = Command::new("sh").arg("-c").arg(cmd).output().await?;
stdout = String::from_utf8_lossy(cmd_out.stdout.as_slice()).to_string();
stderr = String::from_utf8_lossy(cmd_out.stderr.as_slice()).to_string();
}; };
let stdout = String::from_utf8_lossy(cmd_out.stdout.as_slice());
let stderr = String::from_utf8_lossy(cmd_out.stderr.as_slice());
let ec = cmd_out.status.code(); let ec = cmd_out.status.code();
let succ = cmd_out.status.success(); let succ = cmd_out.status.success();
tracing::info!(?cmd, ?ec, ?succ, ?stdout, ?stderr, "run shell cmd"); tracing::info!(?cmd, ?ec, ?succ, ?stdout, ?stderr, "run shell cmd");
if !cmd_out.status.success() { if !cmd_out.status.success() {
return Err(Error::ShellCommandError( return Err(Error::ShellCommandError(
stdout.to_string() + &stderr.to_string(), stdout + &stderr,
)); ));
} }
Ok(()) Ok(())

View File

@ -225,6 +225,22 @@ pub fn init_logger(
Ok(ret_sender) Ok(ret_sender)
} }
#[cfg(target_os = "windows")]
pub fn utf8_or_gbk_to_string(s: &[u8]) -> String {
use encoding::{all::GBK, DecoderTrap, Encoding};
if let Ok(utf8_str) = String::from_utf8(s.to_vec()) {
utf8_str
} else {
// 如果解码失败则尝试使用GBK解码
if let Ok(gbk_str) = GBK.decode(&s, DecoderTrap::Strict) {
gbk_str
} else {
String::from_utf8_lossy(s).to_string()
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::common::config::{self}; use crate::common::config::{self};