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

C#获取Windows用户本地会话信息:实现账户锁定时程序停止运行

Solution for Handling Windows Session Lock & Retrieving Session Info

Hey there! Let's break down how to solve your problem—getting your program to pause when a user locks their Windows account, plus pulling local session details. Here's a straightforward, practical approach:

1. Detect Session Lock/Unlock to Pause/Resume Your Program

For .NET apps, the simplest method is using the SystemEvents.SessionSwitch event, which fires whenever the user locks/unlocks their session, logs on, or switches users.

C# Example:

using Microsoft.Win32;
using System;

class SessionMonitor
{
    static void Main()
    {
        // Hook into session state changes
        SystemEvents.SessionSwitch += OnSessionSwitch;

        // Keep the app running (adjust this logic for WinForms/WPF apps)
        Console.WriteLine("Monitoring session events... Press any key to exit.");
        Console.ReadKey();
    }

    private static void OnSessionSwitch(object sender, SessionSwitchEventArgs e)
    {
        switch (e.Reason)
        {
            case SessionSwitchReason.SessionLock:
                Console.WriteLine("User locked the session—pausing program execution.");
                // Add your custom stop/pause logic here (e.g., halt background tasks, pause threads)
                PauseProgram();
                break;
            case SessionSwitchReason.SessionUnlock:
                Console.WriteLine("User unlocked the session—resuming program execution.");
                // Add your resume logic here
                ResumeProgram();
                break;
        }
    }

    private static void PauseProgram()
    {
        // Implement your pause behavior: e.g., set a flag to pause processing, stop timers
    }

    private static void ResumeProgram()
    {
        // Implement resume behavior: e.g., reset flags, restart timers
    }
}

Quick Notes:

  • For WinForms/WPF apps, this works seamlessly without needing a console to stay open.
  • If you're using a non-.NET language like C++, use the SetWinEventHook function to listen for EVENT_SYSTEM_SESSIONLOCK (0x0007) and EVENT_SYSTEM_SESSIONUNLOCK (0x0008) events directly.

2. Retrieving Local Windows Session Information

To pull details like active session ID, username, or session state, use Windows Terminal Services (WTS) APIs. Here's a C# example using P/Invoke to access these APIs:

Example Code:

using System;
using System.Runtime.InteropServices;

class SessionInfoHelper
{
    // P/Invoke declarations for WTS APIs
    [DllImport("wtsapi32.dll")]
    private static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] string pServerName);

    [DllImport("wtsapi32.dll")]
    private static extern void WTSCloseServer(IntPtr hServer);

    [DllImport("wtsapi32.dll")]
    private static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out IntPtr ppBuffer, out uint pBytesReturned);

    [DllImport("wtsapi32.dll")]
    private static extern void WTSFreeMemory(IntPtr pMemory);

    private enum WTS_INFO_CLASS
    {
        WTSUserName = 5,
        WTSSessionState = 11,
        WTSClientName = 10
        // Add other info classes (like WTSDomainName) as needed
    }

    public static void GetActiveSessionDetails()
    {
        IntPtr serverHandle = WTSOpenServer(Environment.MachineName);
        if (serverHandle == IntPtr.Zero)
        {
            Console.WriteLine("Failed to connect to local server.");
            return;
        }

        // Get the active session ID tied to your program
        int activeSessionId = System.Diagnostics.Process.GetCurrentProcess().SessionId;

        // Fetch username
        if (WTSQuerySessionInformation(serverHandle, activeSessionId, WTS_INFO_CLASS.WTSUserName, out IntPtr usernamePtr, out uint bytesReturned))
        {
            string username = Marshal.PtrToStringAnsi(usernamePtr);
            Console.WriteLine($"Active Session Username: {username}");
            WTSFreeMemory(usernamePtr);
        }

        // Fetch session state
        if (WTSQuerySessionInformation(serverHandle, activeSessionId, WTS_INFO_CLASS.WTSSessionState, out IntPtr statePtr, out uint bytesReturned))
        {
            int state = Marshal.ReadInt32(statePtr);
            Console.WriteLine($"Session State: {(state == 0 ? "Active/Unlocked" : "Locked/Disconnected")}");
            WTSFreeMemory(statePtr);
        }

        WTSCloseServer(serverHandle);
    }
}

// Usage: SessionInfoHelper.GetActiveSessionDetails();

Key Tips:

  • Use WTSEnumerateSessions instead if you need info for all local sessions, not just the active one.
  • For C++ devs, call these WTS APIs directly without needing P/Invoke.

Troubleshooting Quick Hits

  • Ensure your app has sufficient permissions: If running as a service, you may need elevated rights or to enable "interact with desktop" to access session details.
  • For services, use WTSRegisterSessionNotification to receive session change events properly—standard SystemEvents might not work reliably here.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:11:38