使用正则表达式解析 quser.exe 的结果
在任何 .NET 语言中使用正则表达式解析 quser.exe 的结果
引言
这是一个(Unix LR)正则表达式,用于解析来自 quser.exe 的结果,适用于任何 .NET 语言(包括 C#、F# 和 VB.NET)。
(?m)^\s?(?<username>[\w\/.\/_\-]{2,64})\s\s+(?<sessionname>\w?.{0,22})\s\s+(?<sessionid>\d{1,5})\s\s+(?<state>.{0,12})\s\s+(?<idletime>.{0,20})\s\s+(?<logontime>.{0,32})$
背景
最近的一个项目需要能够远程断开用户连接(使用 logoff.exe,它需要一个远程 SessionID
,你可以从 quser.exe 获取)。 在撰写本文时,我找到的唯一其他 quser 解析器是用 Powershell 编写的,我希望在 .NET\WPF 应用程序中使用它,而无需引用 Powershell\System.Management
程序集。
在 Windows 10、Server 2012 和 Server 2008 R2 上测试过。
Using the Code
我创建了以下示例,包括一个简单的接口声明,以保存我们的数据。
请注意,我已从上述正则表达式中删除了多行标志 (?m),而选择使用 .NET 的 RegexOptions.MultiLine
枚举。 这是用于查询和解析 quser 数据的模块
F# 示例
namespace Vivrant.Parsers
module QUser =
open System
open System.Diagnostics
open System.Text.RegularExpressions
type IQUserInformation =
abstract member Username:String with get
abstract member SessionName:String with get
abstract member SessionID:String with get
abstract member State:String with get
abstract member IdleTime:String with get
abstract member LogonTime:DateTime with get
let QueryUsers(serverName:string) =
let args = String.Format(" /SERVER:{0}", serverName)
let cmdQuser = new Process()
cmdQuser.StartInfo.WorkingDirectory <- Environment.CurrentDirectory
cmdQuser.StartInfo.FileName <- "lib\quser.exe"
cmdQuser.StartInfo.Arguments <- args
cmdQuser.StartInfo.UseShellExecute <- false
cmdQuser.StartInfo.RedirectStandardOutput <- true
cmdQuser.StartInfo.CreateNoWindow <- true
cmdQuser.Start()
|> ignore
let stdOut = cmdQuser.StandardOutput.ReadToEnd()
while(not <| cmdQuser.HasExited) do
cmdQuser.WaitForExit()
stdOut
let ParseQUserResults(stdOut) =
let userResults = new ResizeArray<IQUserInformation>()
let quserPattern = @"^\s?(?<username>[\w\/.\/_\-]{2,64})\s\s+(?<sessionname>\w?.{0,22})\s\s+(?<sessionid>\d{1,5})\s\s+(?<state>.{0,12})\s\s+(?<idletime>.{0,20})\s\s+(?<logontime>.{0,32})$"
let regex = new Regex(quserPattern, RegexOptions.Multiline)
let mutable result = regex.Match(stdOut)
while result.Success do
let success, parsedLogonTime = DateTime.TryParse(result.Groups.["logontime"].Value.ToString().Trim())
userResults.Add
{ new IQUserInformation with
member this.Username = result.Groups.["username"].Value.ToString().Trim()
member this.SessionName = result.Groups.["sessionname"].Value.ToString().Trim()
member this.SessionID = result.Groups.["sessionid"].Value.ToString().Trim()
member this.State = result.Groups.["state"].Value.ToString().Trim()
member this.IdleTime = result.Groups.["idletime"].Value.ToString().Trim()
member this.LogonTime =
match success with
| true -> parsedLogonTime
| false -> DateTime.MinValue }
result <- result.NextMatch()
userResults
现在我们可以这样调用它
module Sample =
let userInfo = QUser.ParseQUserResults <| QUser.QueryUsers "myPC"
do ( ) //do something with userInfo
关注点
根据您的架构(例如 32 位与 64 位处理器、操作系统和项目构建设置),您的应用程序可能无法看到文件 c:\Windows\system32\quser.exe, 因为 Windows 虚拟化了对 System 目录的访问。
为了让您的程序看到 `quser.exe`,您可能需要在 SYSTEM32 文件夹之外放置一个它的副本。 在资源管理器中浏览到它,复制并粘贴到其他地方。 为了这个示例,我将其放置在我的项目文件夹的子文件夹“MyProject\lib”中,并将构建选项设置为“始终复制”。
历史
- 2016-12-13:初始发布