You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows 10中SessionEnv服务无法停止的技术问题求助

问题描述

工厂设备操作时,需在手动校准阶段禁用远程桌面(RDP/VNC)以保障安全。开发的控制程序在Windows XP/7上运行正常,但在Windows 10中出现异常:

  • 停止SessionEnv服务时,状态卡在Stopping无法变为Stopped,随后报错Cannot open SessionEnv service on computer
  • 仅能通过终止Service Host: Remote Desktop Services进程恢复
  • 特殊现象:通过Visual Studio启动程序时一切正常,直接运行bin/Debug下的程序则触发问题

涉及服务:

  • SessionEnv
  • TermService

启用/禁用服务的核心代码如下:

启用服务代码

List<string> service_name = new List<string>()
{
    "SessionEnv",
    "TermService"
};

private void Start_Click(object sender, RoutedEventArgs e)
{
    try
    {
        if (!windows.Contains("Windows XP"))
        {
            foreach (var service in service_name)
            {
                ServiceController sc = new ServiceController(service);
                status = Get_Status(service);

                if (status == "Running")
                {
                    continue;
                }

                else if (status == "Stopped")
                {
                    sc.Start();
                }
            }
            count_running = 2;
            count_stopped = 0;
        }

        if (vnc_installed == true)
        {
            Start_VNC();
        }

        ni.ShowBalloonTip(500, "Remote Desktop Enable/Disable Application", "Remote Desktop Connections are enabled", ToolTipIcon.Info);

        startup_status = "Open";

        File.WriteAllText("c:\\temp\\Startup.txt", startup_status);
    }

    catch (Exception ex)
    {
        System.Windows.MessageBox.Show(ex.Message);
    }
}

禁用服务代码

private void Stop_Click(object sender, RoutedEventArgs e)
{
    try
    {
        if (!windows.Contains("Windows XP"))
        {
            foreach (var service in service_name)
            {
                ServiceController sc = new ServiceController(service);
                status = Get_Status(service);

                if (status == "Running")
                {
                    sc.Stop();
                }

                else if (status == "Stopped" )
                {
                    continue;
                }
            }
            count_running = 0;
            count_stopped = 2;
        }

        if (vnc_installed == true)
        {
            Close_VNC();
        }

        ni.ShowBalloonTip(500, "Remote Desktop Enable/Disable Application", "Remote Desktop Connections are disabled", ToolTipIcon.Info);

        startup_status = "Close";
        File.WriteAllText("c:\\temp\\Startup.txt", startup_status);
    }

    catch (Exception ex)
    {
        System.Windows.MessageBox.Show(ex.Message);
    }
}

解决方案

1. 添加管理员权限声明

Visual Studio默认以管理员权限启动程序,而直接运行bin/Debug的程序无此权限,导致服务操作失败。需为程序添加权限声明:

  • 右键项目→添加→新建项→选择「应用程序清单文件」(若已存在则跳过)
  • 修改<requestedExecutionLevel>节点为:
    <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
    
  • 重新编译程序,运行时会自动请求管理员权限

2. 调整服务停止顺序并等待状态变更

Windows 10中SessionEnv服务依赖TermService,直接停止会导致服务挂起。需调整停止顺序,并等待服务状态完成:

private void Stop_Click(object sender, RoutedEventArgs e)
{
    try
    {
        if (!windows.Contains("Windows XP"))
        {
            // 先停止SessionEnv,再停止TermService
            foreach (var service in new List<string>{"SessionEnv", "TermService"})
            {
                ServiceController sc = new ServiceController(service);
                var currentStatus = sc.Status;

                if (currentStatus == ServiceControllerStatus.Running)
                {
                    sc.Stop();
                    // 等待服务停止,超时30秒
                    try
                    {
                        sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30));
                    }
                    catch (TimeoutException)
                    {
                        // 超时后强制结束服务宿主进程
                        KillServiceHost(sc.ServiceName);
                    }
                }
            }
            count_running = 0;
            count_stopped = 2;
        }

        // 原有VNC关闭、提示、文件写入代码不变
    }
    catch (Exception ex)
    {
        System.Windows.MessageBox.Show(ex.Message);
    }
}

// 根据服务名找到对应的宿主进程并终止
private void KillServiceHost(string serviceName)
{
    using (var sc = new ServiceController(serviceName))
    {
        int processId = GetServiceProcessId(sc.ServiceHandle);
        if (processId != 0)
        {
            try
            {
                Process.GetProcessById(processId).Kill();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"无法终止进程: {ex.Message}");
            }
        }
    }
}

// P/Invoke获取服务对应的进程ID
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int GetServiceProcessId(IntPtr hService, out int processId);
private int GetServiceProcessId(IntPtr serviceHandle)
{
    int processId;
    GetServiceProcessId(serviceHandle, out processId);
    return processId;
}

3. 清理残留远程桌面会话

Win10中未关闭的远程会话会导致SessionEnv服务无法正常停止,可在停止服务前先断开所有远程会话:

// 断开所有远程桌面会话
private void DisconnectAllRdpSessions()
{
    ProcessStartInfo psi = new ProcessStartInfo
    {
        FileName = "query.exe",
        Arguments = "session",
        RedirectStandardOutput = true,
        UseShellExecute = false,
        CreateNoWindow = true
    };

    using (Process process = Process.Start(psi))
    {
        string output = process.StandardOutput.ReadToEnd();
        var lines = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

        foreach (var line in lines.Skip(1)) // 跳过表头
        {
            var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length >= 2 && parts[0] != "console") // 跳过本地控制台会话
            {
                string sessionId = parts[0];
                Process.Start("logoff.exe", sessionId).WaitForExit();
            }
        }
    }
}

在Stop_Click方法开头调用DisconnectAllRdpSessions()后再执行服务停止逻辑。


内容的提问来源于stack exchange,提问作者dadou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 15:27:52