194 lines
5.7 KiB
C#
194 lines
5.7 KiB
C#
using Microsoft.Win32;
|
||
using System.Diagnostics;
|
||
|
||
namespace DeviceAgent.Services;
|
||
|
||
/// <summary>
|
||
/// 远程桌面服务 - 自动开启 Windows 远程桌面
|
||
/// </summary>
|
||
public class RemoteDesktopService
|
||
{
|
||
private readonly ILogger<RemoteDesktopService> _logger;
|
||
|
||
public RemoteDesktopService(ILogger<RemoteDesktopService> logger)
|
||
{
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 启用远程桌面
|
||
/// </summary>
|
||
public bool EnableRemoteDesktop()
|
||
{
|
||
try
|
||
{
|
||
// 1. 修改注册表启用远程桌面
|
||
using var key = Registry.LocalMachine.OpenSubKey(
|
||
@"SYSTEM\CurrentControlSet\Control\Terminal Server", true);
|
||
|
||
if (key != null)
|
||
{
|
||
// fDenyTSConnections = 0 表示允许远程连接
|
||
key.SetValue("fDenyTSConnections", 0, RegistryValueKind.DWord);
|
||
_logger.LogInformation("已启用远程桌面连接");
|
||
}
|
||
else
|
||
{
|
||
_logger.LogWarning("无法打开远程桌面注册表项");
|
||
return false;
|
||
}
|
||
|
||
// 2. 设置网络级别身份验证 (NLA) - 可选,设为 0 允许任何版本的远程桌面连接
|
||
using var nlaKey = Registry.LocalMachine.OpenSubKey(
|
||
@"SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp", true);
|
||
|
||
if (nlaKey != null)
|
||
{
|
||
// UserAuthentication = 0 禁用 NLA(更兼容)
|
||
// UserAuthentication = 1 启用 NLA(更安全)
|
||
nlaKey.SetValue("UserAuthentication", 0, RegistryValueKind.DWord);
|
||
_logger.LogInformation("已配置网络级别身份验证");
|
||
}
|
||
|
||
// 3. 开启防火墙规则
|
||
EnableFirewallRule();
|
||
|
||
// 4. 启动远程桌面服务
|
||
StartTerminalService();
|
||
|
||
return true;
|
||
}
|
||
catch (UnauthorizedAccessException ex)
|
||
{
|
||
_logger.LogError(ex, "启用远程桌面失败: 需要管理员权限");
|
||
return false;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "启用远程桌面失败");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查远程桌面是否已启用
|
||
/// </summary>
|
||
public bool IsRemoteDesktopEnabled()
|
||
{
|
||
try
|
||
{
|
||
using var key = Registry.LocalMachine.OpenSubKey(
|
||
@"SYSTEM\CurrentControlSet\Control\Terminal Server");
|
||
|
||
if (key != null)
|
||
{
|
||
var value = key.GetValue("fDenyTSConnections");
|
||
return value != null && (int)value == 0;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "检查远程桌面状态失败");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开启防火墙规则允许远程桌面
|
||
/// </summary>
|
||
private void EnableFirewallRule()
|
||
{
|
||
try
|
||
{
|
||
// 启用远程桌面防火墙规则
|
||
var startInfo = new ProcessStartInfo
|
||
{
|
||
FileName = "netsh",
|
||
Arguments = "advfirewall firewall set rule group=\"远程桌面\" new enable=yes",
|
||
UseShellExecute = false,
|
||
RedirectStandardOutput = true,
|
||
RedirectStandardError = true,
|
||
CreateNoWindow = true
|
||
};
|
||
|
||
using var process = Process.Start(startInfo);
|
||
process?.WaitForExit(5000);
|
||
|
||
// 如果中文规则名失败,尝试英文
|
||
if (process?.ExitCode != 0)
|
||
{
|
||
startInfo.Arguments = "advfirewall firewall set rule group=\"Remote Desktop\" new enable=yes";
|
||
using var process2 = Process.Start(startInfo);
|
||
process2?.WaitForExit(5000);
|
||
}
|
||
|
||
_logger.LogInformation("已配置防火墙规则");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogWarning(ex, "配置防火墙规则失败,可能需要手动配置");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 启动远程桌面服务
|
||
/// </summary>
|
||
private void StartTerminalService()
|
||
{
|
||
try
|
||
{
|
||
var startInfo = new ProcessStartInfo
|
||
{
|
||
FileName = "sc",
|
||
Arguments = "config TermService start= auto",
|
||
UseShellExecute = false,
|
||
RedirectStandardOutput = true,
|
||
CreateNoWindow = true
|
||
};
|
||
|
||
using var process = Process.Start(startInfo);
|
||
process?.WaitForExit(5000);
|
||
|
||
// 启动服务
|
||
startInfo.Arguments = "start TermService";
|
||
using var process2 = Process.Start(startInfo);
|
||
process2?.WaitForExit(5000);
|
||
|
||
_logger.LogInformation("已启动远程桌面服务");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogWarning(ex, "启动远程桌面服务失败");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取远程桌面端口
|
||
/// </summary>
|
||
public int GetRdpPort()
|
||
{
|
||
try
|
||
{
|
||
using var key = Registry.LocalMachine.OpenSubKey(
|
||
@"SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp");
|
||
|
||
if (key != null)
|
||
{
|
||
var value = key.GetValue("PortNumber");
|
||
if (value != null)
|
||
{
|
||
return (int)value;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "获取远程桌面端口失败");
|
||
}
|
||
|
||
return 3389; // 默认端口
|
||
}
|
||
}
|