使用 c# 在本地注销 Windows 用户

Posted

技术标签:

【中文标题】使用 c# 在本地注销 Windows 用户【英文标题】:Log off a Windows user locally using c# 【发布时间】:2013-01-06 03:28:30 【问题描述】:

我目前正在开发一些家长控制软件。该软件应该注销用户然后锁定帐户,以便他们无法重新登录,除非父母/管理员指定他们可以。

到目前为止,我已经尝试了几件事,例如在用户帐户上设置标志,说明它已被禁用。这会将其从登录屏幕中完全删除。据我所知,如果用户帐户已登录,则不会应用 ADS_Disable 标志。我还尝试寻找有关注销另一个帐户的资源,但我似乎只能找到有关注销正在运行 logout 命令的帐户的信息。如Pinvoke,或者直接调用LOGOUT.EXE程序。

我在LSAUser 上找到了一个资源,发现那里可能有一些东西。我正在为学校做这个项目,我需要一些指导。由于这样做的信息很少,有没有更好的方法来做我想做的事情?或者有什么理由我不应该这样做?有其他选择吗?

【问题讨论】:

windows.microsoft.com/en-US/windows7/products/features/… 必须是您可以绑定的 api,这样您就不必重新发明***。 我正在尝试为 Windows XP 执行此操作,据我所知,家庭中心不支持 XP。 您可能想查看***.com/questions/12112506/…。这是假设您不介意非 C# 解决方案。似乎是基于 powershell 的,这是执行此类任务的事实上的方式。 自 Windows 2000 以来,Windows 已支持基于时间的用户锁定。请查看 Windows XP Home Edition 支持的组策略。 我发现这个***.com/questions/484278/… 可能有帮助 【参考方案1】:

使用WTSDisconnectSession() Windows API。见文章here。

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;

class Program

  [DllImport("wtsapi32.dll", SetLastError = true)]
  static extern bool WTSDisconnectSession(IntPtr hServer, int sessionId, bool bWait);

  [DllImport("Kernel32.dll", SetLastError = true)]         
  static extern WTSGetActiveConsoleSessionId();

  const int WTS_CURRENT_SESSION = -1;
  static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;

  static void Main(string[] args)
  
    if (!WTSDisconnectSession(WTS_CURRENT_SERVER_HANDLE,
         WTS_CURRENT_SESSION, false))
      throw new Win32Exception();
  

即使没有远程桌面,它也会断开当前用户并进入登录屏幕。这些进程仍将在后台运行。再次手动登录后,正在运行的程序将显示为断开前的状态。

【讨论】:

这太棒了,你知道如何获取用户会话ID吗?我可以从 WMI 获取它吗? 你使用[DllImport("Kernel32.dll", SetLastError = true)] static extern UInt32 WTSGetActiveConsoleSessionId();,因为我读到它来自:social.msdn.microsoft.com/Forums/en-US/windowssecurity/thread/… WTSEnumerateSessions() 来自***.com/questions/132620/… @esmehsnj 我不知道。 UWP 是否支持 WinAPI?也许不是。 @JohnAlexiou 显然不是,根据这个答案我们可以在WinRT ***.com/a/42445105/6908213中找到等价的函数【参考方案2】:
  [DllImport("wtsapi32.dll", SetLastError = true)]
  static extern bool WTSDisconnectSession(IntPtr hServer, int sessionId, bool bWait);

当您在远程桌面中使用 WTSDisconnectSession 时,相当于“关闭”远程桌面窗口。它正在断开您的 Windows 会话,但保持连接。 优点是您可以稍后通过再次远程登录重新连接会话。 缺点是当远程桌面连接已满时,其他用户可能无法登录 Windows。 要模拟 Windows 的“注销”,应使用 user32.dll 下的 ExitWindowsEx

[DllImport("user32.dll", SetLastError = true)]
static extern bool ExitWindowsEx(uint uFlags, uint dwReason);

public static bool WindowsLogOff() 
  return ExitWindowsEx(0, 0);

如果你想强制用户注销,你需要像这样添加EWX_FORCE 标志:

ExitWindowsEx(0 | 0x00000004, 0);

这里有更多关于函数的详细信息:https://msdn.microsoft.com/en-us/library/windows/desktop/aa376868(v=vs.85).aspx

【讨论】:

如何注销其他登录用户?【参考方案3】:

捎带 Leng Weh Seng 的回答(因为我无法评论),如果你想强制用户注销,你需要像这样添加 EWX_FORCE 标志:

ExitWindowsEx(0 | 0x00000004, 0);

这里有更多关于函数的详细信息:https://msdn.microsoft.com/en-us/library/windows/desktop/aa376868(v=vs.85).aspx

【讨论】:

这相当于ExitWindowsEx(4, 0);

以上是关于使用 c# 在本地注销 Windows 用户的主要内容,如果未能解决你的问题,请参考以下文章

注销当前用户后 Win10找不到Administrator用户登录选项怎么解决

使用 Python 注销 Windows

win10 修改c盘用户文件夹名称

无法使用 Facebook C# SDK 注销 Facebook

如何让 .NET Windows 服务检测登录、注销和切换用户事件?

Windows10系统怎样切换到本地账户 Windows10系统切换本地登录的方法