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

如何监听Win32_TerminalServiceSetting的Logons属性变更?

问题

需要监听WMI类Win32_TerminalServiceSetting的Logons属性变更,当通过cmd执行change logon /disable或/enable修改该属性时,程序能触发对应操作。现有查询属性的基础代码,但不想用循环查询,尝试用WqlEventQuery实现监听却未触发事件,需排查并给出正确方案。

原有查询代码

// 创建管理作用域
ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\CIMV2\\TerminalServices");

// 创建对象查询
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_TerminalServiceSetting");

// 创建对象搜索器
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

// 获取WMI对象集合
ManagementObjectCollection queryCollection = searcher.Get();

// 遍历集合
foreach (ManagementObject m in queryCollection) 
{
  // 访问WMI对象属性
  Console.WriteLine("Logons: {0}", m["Logons"]);
}

尝试的监听代码(未触发)

public class eventWatcher
{
    public eventWatcher()
    {
        WqlEventQuery query;
        ManagementScope scope = new ManagementScope("root\\CIMV2\\TerminalServices");
        scope.Options.EnablePrivileges = true;
        try
        {
            query = new WqlEventQuery();
            query.EventClassName = "__InstanceCreationEvent";
            query.WithinInterval = new TimeSpan(0, 0, 3);
            query.Condition = "TargetInstance ISA 'Win32_TerminalServiceSetting'";
            var eventWatcher = new ManagementEventWatcher(scope, query);
            eventWatcher.EventArrived += new EventArrivedEventHandler(this.HandleEvent);
            eventWatcher.Start();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

    private void HandleEvent(object sender, EventArrivedEventArgs e)
    {
        Console.WriteLine("got new event");
    }
}
问题排查
  1. 事件类型错误:__InstanceCreationEvent仅在新实例创建时触发,但Win32_TerminalServiceSetting是系统单实例对象,执行change logon命令只会修改现有实例的属性,不会创建新实例,因此该事件永远不会触发。
  2. 未过滤目标属性:即使使用正确的修改事件,若不指定监听Logons属性,会触发所有无关属性的修改事件,造成冗余。
正确实现方案

使用__InstanceModificationEvent监听实例属性修改,并添加条件过滤仅关注Logons属性的变化。同时确保代码拥有足够权限(需管理员身份运行)。

完整监听代码

public class TerminalServiceLogonsWatcher
{
    private ManagementEventWatcher _eventWatcher;

    public TerminalServiceLogonsWatcher()
    {
        // 设置WMI作用域
        var scope = new ManagementScope(@"\\.\ROOT\CIMV2\TerminalServices");
        scope.Options.EnablePrivileges = true;
        scope.Options.Impersonation = ImpersonationLevel.Impersonate;
        
        try
        {
            // 构建WQL事件查询:监听Win32_TerminalServiceSetting的Logons属性修改
            var query = new WqlEventQuery
            {
                EventClassName = "__InstanceModificationEvent",
                WithinInterval = TimeSpan.FromSeconds(1), // 检测间隔,可按需调整
                Condition = @"TargetInstance ISA 'Win32_TerminalServiceSetting' 
                            AND PreviousInstance.Logons != TargetInstance.Logons"
            };

            _eventWatcher = new ManagementEventWatcher(scope, query);
            _eventWatcher.EventArrived += OnLogonsChanged;
            _eventWatcher.Start();
            Console.WriteLine("已开始监听Logons属性变更");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"监听初始化失败: {ex.Message}");
        }
    }

    private void OnLogonsChanged(object sender, EventArrivedEventArgs e)
    {
        // 获取变更前后的实例
        var previousInstance = (ManagementBaseObject)e.NewEvent["PreviousInstance"];
        var targetInstance = (ManagementBaseObject)e.NewEvent["TargetInstance"];

        var oldLogonsValue = previousInstance["Logons"]?.ToString();
        var newLogonsValue = targetInstance["Logons"]?.ToString();

        Console.WriteLine($"Logons属性已变更: 旧值={oldLogonsValue}, 新值={newLogonsValue}");
        
        // 根据新值执行对应操作
        switch (newLogonsValue)
        {
            case "0": // 对应disable状态
                Console.WriteLine("执行Logons禁用后的操作");
                break;
            case "1": // 对应enable状态
                Console.WriteLine("执行Logons启用后的操作");
                break;
        }
    }

    // 停止监听的方法,按需调用
    public void StopWatching()
    {
        _eventWatcher?.Stop();
        _eventWatcher?.Dispose();
        Console.WriteLine("已停止监听Logons属性变更");
    }
}

使用方式

// 启动监听
var watcher = new TerminalServiceLogonsWatcher();

// 保持程序运行(控制台程序示例)
Console.WriteLine("按任意键停止监听...");
Console.ReadKey();

// 停止监听
watcher.StopWatching();

注意事项

  • 管理员权限:程序必须以管理员身份运行,否则无法访问终端服务相关WMI对象和监听事件。
  • 属性值对应关系:Win32_TerminalServiceSetting.Logons的取值:
    • 0:已禁用登录(对应change logon /disable)
    • 1:已启用登录(对应change logon /enable)
  • 检测间隔:WithinInterval可根据需求调整,值越小响应越快,但系统资源消耗略高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 08:35:37