读取输出C#的特定部分

时间:2019-12-05 18:34:51

标签: c# cmd

我正在为我们的IT部门创建一个UI,以遮盖用户的会话。首先,您必须使用以下命令获取会话ID。

        Process Process = new Process();
        ProcessStartInfo startInfo = new ProcessStartInfo("CMD.exe", "/K" + "qwinsta /server:" + ComputerName + " " + Username);
        startInfo.CreateNoWindow = false;
        startInfo.UseShellExecute = true;

        Process = Process.Start(startInfo);

这就是你得到的东西。

 SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE
 console           mlynch                    8  Active

截至目前,这将打开此命令的命令提示符,其中包含您在几个文本框中输入的计算机名称和用户名。然后,您获取会话ID,并将其输入到第3个文本框中,然后单击连接按钮。我试图绕过这一步。输入计算机和用户名,单击连接即可。我需要找到一种方法来获取会话ID并将其保存为字符串,然后在下一行代码中引用该字符串。

        if (MouseControlCheck.Checked == true)
        {
        Process Process = new Process();
        ProcessStartInfo startInfo = new ProcessStartInfo("CMD.exe", "/C" + "mstsc.exe /shadow:" + SessionID + " /v " + ComputerName + " /control");
        startInfo.CreateNoWindow = true;
        startInfo.UseShellExecute = false;

        Process = Process.Start(startInfo);
        }
        else
        {
        Process Process = new Process();
        ProcessStartInfo startInfo = new ProcessStartInfo("CMD.exe", "/C" + "mstsc.exe /shadow:" + SessionID + " /v " + ComputerName);
        startInfo.CreateNoWindow = true;
        startInfo.UseShellExecute = false;

        Process = Process.Start(startInfo);
        }

如何将会话ID读取为字符串?

TLDR:我想跳过控制台和Mlynch,然后转到ID下的数字。这将不会用于获取本地计算机ID,我需要网络上计算机的ID。

4 个答案:

答案 0 :(得分:0)

来自MS site

您需要添加RedirectStandardOutput = true,然后读取Standardoutput。

string[] allLines;
using (Process process = new Process())
        {
            process.StartInfo.FileName = "ipconfig.exe";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.Start();

            // Synchronously read the standard output of the spawned process. 
            StreamReader reader = process.StandardOutput;
            string output = reader.ReadToEnd();

            // Convert all text to string array
            allLines = output.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

            // Write the redirected output to this application's window.
            Console.WriteLine(output);

            process.WaitForExit();
        }

答案 1 :(得分:0)

基于本文c# how to determine session id of specific logged in windows user,仅使用Windows api来获取用户会话信息可能会更容易。这样就无需调用cmd并解析输出。我对其进行了一些修改,以获得特定的用户

class Program
{
    static void Main(string[] args)
    {

        // this code gets the users from localhost -
        // can change this to a remote hostname on the network
        Console.Write(UserLogins.GetUser("COMPUTER_NAME", "USER_NAME"));

        Console.ReadKey();

    }

    public class UserLogins
    {

        [DllImport("wtsapi32.dll")]
        static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);

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

        [DllImport("wtsapi32.dll")]
        static extern Int32 WTSEnumerateSessions(
            IntPtr hServer,
            [MarshalAs(UnmanagedType.U4)] Int32 Reserved,
            [MarshalAs(UnmanagedType.U4)] Int32 Version,
            ref IntPtr ppSessionInfo,
            [MarshalAs(UnmanagedType.U4)] ref Int32 pCount);

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

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

        [StructLayout(LayoutKind.Sequential)]
        private struct WTS_SESSION_INFO
        {
            public Int32 SessionID;

            [MarshalAs(UnmanagedType.LPStr)]
            public String pWinStationName;

            public WTS_CONNECTSTATE_CLASS State;
        }

        public enum WTS_INFO_CLASS
        {
            WTSInitialProgram,
            WTSApplicationName,
            WTSWorkingDirectory,
            WTSOEMId,
            WTSSessionId,
            WTSUserName,
            WTSWinStationName,
            WTSDomainName,
            WTSConnectState,
            WTSClientBuildNumber,
            WTSClientName,
            WTSClientDirectory,
            WTSClientProductId,
            WTSClientHardwareId,
            WTSClientAddress,
            WTSClientDisplay,
            WTSClientProtocolType
        }
        public enum WTS_CONNECTSTATE_CLASS
        {
            WTSActive,
            WTSConnected,
            WTSConnectQuery,
            WTSShadow,
            WTSDisconnected,
            WTSIdle,
            WTSListen,
            WTSReset,
            WTSDown,
            WTSInit
        }

        public static IntPtr OpenServer(String Name)
        {
            IntPtr server = WTSOpenServer(Name);
            return server;
        }
        public static void CloseServer(IntPtr ServerHandle)
        {
            WTSCloseServer(ServerHandle);
        }

        public static UserInfo GetUser(string server, string username)
        {
            return GetUsers(server).FirstOrDefault(c => c.User.Equals(username, StringComparison.InvariantCultureIgnoreCase));
        }

        public static IEnumerable<UserInfo> GetUsers(String ServerName)
        {
            IntPtr serverHandle = IntPtr.Zero;
            List<String> resultList = new List<string>();
            serverHandle = OpenServer(ServerName);

            try
            {
                IntPtr SessionInfoPtr = IntPtr.Zero;
                IntPtr userPtr = IntPtr.Zero;
                IntPtr domainPtr = IntPtr.Zero;
                Int32 sessionCount = 0;
                Int32 retVal = WTSEnumerateSessions(serverHandle, 0, 1, ref SessionInfoPtr, ref sessionCount);
                Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
                Int32 currentSession = (int)SessionInfoPtr;
                uint bytes = 0;

                if (retVal != 0)
                {
                    for (int i = 0; i < sessionCount; i++)
                    {
                        WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTS_SESSION_INFO));
                        currentSession += dataSize;

                        WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes);
                        WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes);

                        yield return new UserInfo
                        {
                            Domain = Marshal.PtrToStringAnsi(domainPtr),
                            User = Marshal.PtrToStringAnsi(userPtr),
                            SessionID = si.SessionID
                        };

                        WTSFreeMemory(userPtr);
                        WTSFreeMemory(domainPtr);
                    }

                    WTSFreeMemory(SessionInfoPtr);
                }
            }
            finally
            {
                CloseServer(serverHandle);
            }
        }
    }
    public class UserInfo
    {
        public string Domain { get; set; }
        public string User { get; set; }

        public int SessionID { get; set; }

        public override string ToString()
        {
            return string.Format("{0}\\{1}: {2}", Domain, User, SessionID);
        }
    }
}

答案 2 :(得分:0)

您的问题的另一种解决方案是使用WMI(甚至是远程)获取用户信息,从而完全避免输出重定向:

using Microsoft.Management.Infrastructure;

string Namespace = @"root\cimv2";
string OSQuery = "SELECT * FROM Win32_OperatingSystem";
CimSession mySession = CimSession.Create("Computer_B");
IEnumerable<CimInstance> queryInstance = mySession.QueryInstances(Namespace, "WQL", OSQuery);

答案 3 :(得分:0)

我明白了我该怎么做。

                Process GetSessionID = new Process();
                GetSessionID.StartInfo.FileName = "CMD.exe";
                GetSessionID.StartInfo.Arguments = "/C" + "for /f \"skip=1 tokens=3\" %1 in ('query user " + Username + "/server:" + ComputerName + "') do @echo %1";
                GetSessionID.StartInfo.RedirectStandardOutput = true;
                GetSessionID.StartInfo.UseShellExecute = false;
                GetSessionID.StartInfo.CreateNoWindow = true;
                GetSessionID.Start();
                SessionIDOutput = GetSessionID.StandardOutput.ReadToEnd();
                GetSessionID.WaitForExit();
                DoAllTheThingsTextBox.Text = SessionIDOutput;
                if (GetSessionID.HasExited == true)
                {
                    var digitArray = DoAllTheThingsTextBox.Text.Where(Char.IsDigit).ToArray();
                    SessionID = new String(digitArray);

                    if (MouseControlCheck.Checked == true)
                    {
                        Process Process = new Process();
                        ProcessStartInfo startInfo = new ProcessStartInfo("CMD.exe", "/C" + "mstsc /shadow:" + SessionID + " /v " + ComputerName + " /control");
                        startInfo.CreateNoWindow = true;
                        startInfo.UseShellExecute = false;

                        Process = Process.Start(startInfo);
                    }
                    else
                    {
                        Process Process = new Process();
                        ProcessStartInfo startInfo = new ProcessStartInfo("CMD.exe", "/C" + "mstsc /shadow:" + SessionID + " /v " + ComputerName);
                        startInfo.CreateNoWindow = true;
                        startInfo.UseShellExecute = false;

                        Process = Process.Start(startInfo);
                    }
                }