65.9K
CodeProject 正在变化。 阅读更多。
Home

使用正则表达式解析 quser.exe 的结果

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2016年12月14日

CPOL

1分钟阅读

viewsIcon

19260

在任何 .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:初始发布
© . All rights reserved.