Files
YMhut-box-C-/参考/NexBox-main/src-tauri/src/network_optimize.rs
T

404 lines
15 KiB
Rust

use std::collections::HashMap;
use std::os::windows::process::CommandExt;
use std::process::Command;
use std::{env, path::Path};
use crate::optimization::{run_simple_feature, PerfTweakResult, CREATE_NO_WINDOW};
fn get_powershell_path() -> String {
if let Ok(sysroot) = env::var("SystemRoot") {
let ps_path = format!(r"{}\System32\WindowsPowerShell\v1.0\powershell.exe", sysroot);
if Path::new(&ps_path).exists() {
return ps_path;
}
}
"powershell.exe".to_string()
}
// === 1. TCP 拥塞控制优化 ===
#[tauri::command]
pub async fn set_tcp_congestion() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'Stop'
$current = netsh int tcp show supplemental 2>&1 | Select-String "拥塞控制提供程序|Congestion Control Provider"
$hasCtcp = $current -match "CTCP|CUBIC"
if (-not $hasCtcp) {
$output = netsh int tcp set supplemental Internet congestionprovider=ctcp 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "TCP 拥塞控制设置失败: $output"
exit 1
}
}
Write-Output 'OK'
"#)
}
#[tauri::command]
pub async fn restore_tcp_congestion() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'Stop'
$output = netsh int tcp set supplemental Internet congestionprovider=newreno 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "TCP 拥塞控制恢复失败: $output"
exit 1
}
Write-Output 'OK'
"#)
}
// === 2. TCP Chimney Offload ===
#[tauri::command]
pub async fn set_tcp_chimney_off() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'Stop'
$output = netsh int tcp set global chimney=disabled 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "TCP Chimney Offload 设置失败: $output"
exit 1
}
Write-Output 'OK'
"#)
}
#[tauri::command]
pub async fn restore_tcp_chimney() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'Stop'
$output = netsh int tcp set global chimney=enabled 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "TCP Chimney Offload 恢复失败: $output"
exit 1
}
Write-Output 'OK'
"#)
}
// === 3. Nagle 算法低延迟策略 ===
#[tauri::command]
pub async fn set_nagle_optimization() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'SilentlyContinue'
$interfaces = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
foreach ($iface in $interfaces) {
$guid = $iface.PSChildName
$path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\$guid"
$ipEnabled = (Get-ItemProperty -Path $path -Name "IPAddress" -ErrorAction SilentlyContinue).IPAddress
if ($ipEnabled) {
Set-ItemProperty -Path $path -Name "TCPNoDelay" -Value 1 -Type DWord -Force -ErrorAction SilentlyContinue
Set-ItemProperty -Path $path -Name "TcpAckFrequency" -Value 1 -Type DWord -Force -ErrorAction SilentlyContinue
Set-ItemProperty -Path $path -Name "TcpDelAckTicks" -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
}
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "TcpAckFrequency" -Value 1 -Type DWord -Force -ErrorAction SilentlyContinue
Write-Output 'OK'
"#)
}
#[tauri::command]
pub async fn restore_nagle_optimization() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'SilentlyContinue'
$interfaces = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
foreach ($iface in $interfaces) {
$guid = $iface.PSChildName
$path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\$guid"
$ipEnabled = (Get-ItemProperty -Path $path -Name "IPAddress" -ErrorAction SilentlyContinue).IPAddress
if ($ipEnabled) {
Remove-ItemProperty -Path $path -Name "TCPNoDelay" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path $path -Name "TcpAckFrequency" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path $path -Name "TcpDelAckTicks" -ErrorAction SilentlyContinue
}
}
Remove-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "TcpAckFrequency" -ErrorAction SilentlyContinue
Write-Output 'OK'
"#)
}
// === 4. 禁用网卡省电模式 ===
#[tauri::command]
pub async fn set_adapter_power_saving_off() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'SilentlyContinue'
$adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue
foreach ($adapter in $adapters) {
Disable-NetAdapterPowerManagement -Name $adapter.Name -ErrorAction SilentlyContinue | Out-Null
}
Write-Output 'OK'
"#)
}
#[tauri::command]
pub async fn restore_adapter_power_saving() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'SilentlyContinue'
$adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue
foreach ($adapter in $adapters) {
Enable-NetAdapterPowerManagement -Name $adapter.Name -ErrorAction SilentlyContinue | Out-Null
}
Write-Output 'OK'
"#)
}
// === 5. DNS 优化 ===
#[tauri::command]
pub async fn set_dns_servers(dns_primary: String, dns_secondary: String) -> Result<PerfTweakResult, String> {
if !cfg!(target_os = "windows") {
return Err("此功能仅支持 Windows 系统".to_string());
}
let script = format!(
r#"
$ErrorActionPreference = 'SilentlyContinue'
$adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue | Where-Object {{ $_.Status -eq "Up" }}
foreach ($adapter in $adapters) {{
Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex -ServerAddresses ("{0}", "{1}") -ErrorAction SilentlyContinue | Out-Null
}}
Write-Output 'OK'
"#,
dns_primary, dns_secondary
);
let ps_path = get_powershell_path();
let result = Command::new(&ps_path)
.args(&["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", &script])
.creation_flags(CREATE_NO_WINDOW)
.output()
.map_err(|e| format!("执行命令失败: {}", e))?;
if result.status.success() {
Ok(PerfTweakResult { success: true, message: format!("DNS 已切换到 {} / {}", dns_primary, dns_secondary) })
} else {
let stderr = String::from_utf8_lossy(&result.stderr).to_string();
let stdout = String::from_utf8_lossy(&result.stdout).to_string();
let err_msg = if !stderr.trim().is_empty() { stderr.trim().to_string() } else { stdout.trim().to_string() };
let lower = err_msg.to_lowercase();
if lower.contains("access denied") || lower.contains("denied") || lower.contains("拒绝访问") || lower.contains("权限不足") {
Err("需要管理员权限,请以管理员身份运行 NexBox".to_string())
} else {
Err(format!("DNS 设置失败: {}", err_msg))
}
}
}
#[tauri::command]
pub async fn restore_dns_servers() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'SilentlyContinue'
$adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq "Up" }
foreach ($adapter in $adapters) {
Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex -ResetServerAddresses -ErrorAction SilentlyContinue | Out-Null
}
Write-Output 'OK'
"#)
}
// === 6. 状态检测 ===
#[derive(serde::Serialize)]
pub struct NetworkTweakState {
pub tcp_congestion_optimized: bool,
pub chimney_offload: bool,
pub nagle_optimized: bool,
pub adapter_power_saving_off: bool,
pub dns_primary: String,
pub dns_secondary: String,
}
#[tauri::command]
pub async fn check_network_tweak_states() -> Result<NetworkTweakState, String> {
if !cfg!(target_os = "windows") {
return Err("此功能仅支持 Windows 系统".to_string());
}
let script = r#"
$ErrorActionPreference = 'SilentlyContinue'
$r = @{}
# TCP Congestion
try {
$supp = netsh int tcp show supplemental 2>$null | Out-String
$r['tcp_congestion'] = ($supp -match "CTCP" -or $supp -match "CUBIC")
} catch { $r['tcp_congestion'] = $false }
# Chimney Offload
try {
$global = netsh int tcp show global 2>$null | Out-String
$r['chimney'] = ($global -match "Chimney Offload State.*disabled" -or $global -match "Chimney 卸载状态.*禁用")
} catch { $r['chimney'] = $false }
# Nagle (check registry)
try {
$firstIface = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces" -ErrorAction SilentlyContinue |
Where-Object { (Get-ItemProperty $_.PSPath -Name "IPAddress" -EA 0).IPAddress } |
Select-Object -First 1
if ($firstIface) {
$tcpNoDelay = (Get-ItemProperty $firstIface.PSPath -Name "TCPNoDelay" -EA 0).TCPNoDelay
$r['nagle'] = ($tcpNoDelay -eq 1)
} else {
$r['nagle'] = $false
}
} catch { $r['nagle'] = $false }
# Adapter Power Saving
try {
$powerMgmtDisabled = Get-NetAdapter -Physical -EA 0 | Where-Object { $_.PowerManagementEnabled -eq $false }
$r['powerSaving'] = ($powerMgmtDisabled.Count -gt 0)
} catch { $r['powerSaving'] = $false }
# DNS
try {
$dnsAdapter = Get-DnsClientServerAddress -AddressFamily IPv4 -EA 0 | Where-Object { $_.ServerAddresses -ne $null } | Select-Object -First 1
if ($dnsAdapter -and $dnsAdapter.ServerAddresses) {
$addrs = $dnsAdapter.ServerAddresses
$r['dns_primary'] = $addrs[0]
$r['dns_secondary'] = if ($addrs.Count -gt 1) { $addrs[1] } else { "" }
} else {
$r['dns_primary'] = ""
$r['dns_secondary'] = ""
}
} catch {
$r['dns_primary'] = ""
$r['dns_secondary'] = ""
}
# 始终输出所有 key,确保前端能解析到
@("tcp_congestion","chimney","nagle","powerSaving","dns_primary","dns_secondary") | ForEach-Object {
Write-Host "$($_):$($r[$_])"
}
"#;
let ps_path = get_powershell_path();
let result = Command::new(&ps_path)
.args(&["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", &script])
.creation_flags(CREATE_NO_WINDOW)
.output()
.map_err(|e| format!("执行检测命令失败: {}", e))?;
if !result.status.success() {
return Err("检测状态失败".to_string());
}
let stdout = String::from_utf8_lossy(&result.stdout);
let mut state = HashMap::new();
for line in stdout.lines() {
if let Some(pos) = line.find(':') {
let key = line[..pos].trim().to_string();
let value = line[pos + 1..].trim().to_string();
state.insert(key, value);
}
}
let tcp_congestion = state.get("tcp_congestion").map(|v| v == "True").unwrap_or(false);
let chimney = state.get("chimney").map(|v| v == "True").unwrap_or(false);
let nagle = state.get("nagle").map(|v| v == "True").unwrap_or(false);
let power_saving = state.get("powerSaving").map(|v| v == "True").unwrap_or(false);
let dns_primary = state.get("dns_primary").cloned().unwrap_or_default();
let dns_secondary = state.get("dns_secondary").cloned().unwrap_or_default();
Ok(NetworkTweakState {
tcp_congestion_optimized: tcp_congestion,
chimney_offload: chimney,
nagle_optimized: nagle,
adapter_power_saving_off: power_saving,
dns_primary,
dns_secondary,
})
}
// === 7. 批量优化 / 恢复(单次 PowerShell 调用) ===
#[tauri::command]
pub async fn batch_network_enable() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'Stop'
# TCP Congestion
$current = netsh int tcp show supplemental 2>&1 | Select-String "拥塞控制提供程序|Congestion Control Provider"
$hasCtcp = $current -match "CTCP|CUBIC"
if (-not $hasCtcp) {
$output = netsh int tcp set supplemental Internet congestionprovider=ctcp 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "TCP 拥塞控制设置失败: $output"
exit 1
}
}
# Chimney Offload
$output = netsh int tcp set global chimney=disabled 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "TCP Chimney Offload 设置失败: $output"
exit 1
}
# Nagle Optimization
$interfaces = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
foreach ($iface in $interfaces) {
$guid = $iface.PSChildName
$path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\$guid"
$ipEnabled = (Get-ItemProperty -Path $path -Name "IPAddress" -ErrorAction SilentlyContinue).IPAddress
if ($ipEnabled) {
Set-ItemProperty -Path $path -Name "TCPNoDelay" -Value 1 -Type DWord -Force -ErrorAction SilentlyContinue
Set-ItemProperty -Path $path -Name "TcpAckFrequency" -Value 1 -Type DWord -Force -ErrorAction SilentlyContinue
Set-ItemProperty -Path $path -Name "TcpDelAckTicks" -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
}
}
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "TcpAckFrequency" -Value 1 -Type DWord -Force -ErrorAction SilentlyContinue
# Adapter Power Saving
$adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue
foreach ($adapter in $adapters) {
Disable-NetAdapterPowerManagement -Name $adapter.Name -ErrorAction SilentlyContinue | Out-Null
}
Write-Output 'OK'
"#)
}
#[tauri::command]
pub async fn batch_network_disable() -> Result<PerfTweakResult, String> {
run_simple_feature(r#"
$ErrorActionPreference = 'Stop'
# TCP Congestion - restore
$output = netsh int tcp set supplemental Internet congestionprovider=newreno 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "TCP 拥塞控制恢复失败: $output"
exit 1
}
# Chimney Offload - restore
$output = netsh int tcp set global chimney=enabled 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "TCP Chimney Offload 恢复失败: $output"
exit 1
}
# Nagle - restore
$interfaces = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
foreach ($iface in $interfaces) {
$guid = $iface.PSChildName
$path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\$guid"
$ipEnabled = (Get-ItemProperty -Path $path -Name "IPAddress" -ErrorAction SilentlyContinue).IPAddress
if ($ipEnabled) {
Remove-ItemProperty -Path $path -Name "TCPNoDelay" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path $path -Name "TcpAckFrequency" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path $path -Name "TcpDelAckTicks" -ErrorAction SilentlyContinue
}
}
Remove-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "TcpAckFrequency" -ErrorAction SilentlyContinue
# Adapter Power Saving - restore
$adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue
foreach ($adapter in $adapters) {
Enable-NetAdapterPowerManagement -Name $adapter.Name -ErrorAction SilentlyContinue | Out-Null
}
Write-Output 'OK'
"#)
}