会话是否是交互式会话

会话是否是交互式会话

本文介绍了如何知道 Windows 会话是否是交互式会话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个服务,它将在用户交互会话上运行进程.我找到了如何从服务中的会话 0 启动进程,我找到了如何在用户登录时捕获.

I'm creating a service that will run processes on user interactive session. I found how to start process from session 0 in a service, I found how to catch when a user is logged on.

但我需要知道 Windows 会话是交互式会话还是交互式 Windows 会话列表.

But I need to know if a Windows session is an interactive one or the list of interactive Windows sessions.

推荐答案

首先设置您的互操作声明.这是最难的部分

DllImport("secur32.dll", SetLastError = false)]
private static extern uint LsaFreeReturnBuffer(IntPtr buffer);

[DllImport("Secur32.dll", SetLastError = false)]
private static extern uint LsaEnumerateLogonSessions
        (out UInt64 LogonSessionCount, out IntPtr LogonSessionList);

[DllImport("Secur32.dll", SetLastError = false)]
private static extern uint LsaGetLogonSessionData(IntPtr luid,
    out IntPtr ppLogonSessionData);

[StructLayout(LayoutKind.Sequential)]
private struct LSA_UNICODE_STRING
{
    public UInt16 Length;
    public UInt16 MaximumLength;
    public IntPtr buffer;
}

[StructLayout(LayoutKind.Sequential)]
private struct LUID
{
    public UInt32 LowPart;
    public UInt32 HighPart;
}

[StructLayout(LayoutKind.Sequential)]
private struct SECURITY_LOGON_SESSION_DATA
{
    public UInt32 Size;
    public LUID LoginID;
    public LSA_UNICODE_STRING Username;
    public LSA_UNICODE_STRING LoginDomain;
    public LSA_UNICODE_STRING AuthenticationPackage;
    public UInt32 LogonType;
    public UInt32 Session;
    public IntPtr PSiD;
    public UInt64 LoginTime;
    public LSA_UNICODE_STRING LogonServer;
    public LSA_UNICODE_STRING DnsDomainName;
    public LSA_UNICODE_STRING Upn;
}

private enum SECURITY_LOGON_TYPE : uint
{
    Interactive = 2,        //The security principal is logging on
                            //interactively.
    Network,                //The security principal is logging using a
                            //network.
    Batch,                  //The logon is for a batch process.
    Service,                //The logon is for a service account.
    Proxy,                  //Not supported.
    Unlock,                 //The logon is an attempt to unlock a workstation.
    NetworkCleartext,       //The logon is a network logon with cleartext
                            //credentials.
    NewCredentials,         //Allows the caller to clone its current token and
                            //specify new credentials for outbound connections.
    RemoteInteractive,      //A terminal server session that is both remote
                            //and interactive.
    CachedInteractive,      //Attempt to use the cached credentials without
                            //going out across the network.
    CachedRemoteInteractive,// Same as RemoteInteractive, except used
                            // internally for auditing purposes.
    CachedUnlock            // The logon is an attempt to unlock a workstation.
}

下一步枚举并提取信息

  UInt64 count;
  IntPtr luidPtr = IntPtr.Zero;
  LsaEnumerateLogonSessions(out count, out luidPtr);  //gets an array of
                                                      //pointers to LUIDs

  IntPtr iter = luidPtr;                              //set the pointer to the
                                                      //start of the array

  for (ulong i = 0; i < count; i++)                   //for each pointer in the
                                                      //array
  {
      IntPtr sessionData;

      LsaGetLogonSessionData(iter, out sessionData);
      SECURITY_LOGON_SESSION_DATA data =(
          SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure
                (sessionData, typeof(SECURITY_LOGON_SESSION_DATA));

      //if we have a valid logon
      if (data.PSiD != IntPtr.Zero)
      {
          //get the security identifier for further use
          System.Security.Principal.SecurityIdentifier sid =
          new System.Security.Principal.SecurityIdentifier(data.PSiD);

          SECURITY_LOGON_TYPE secType = (SECURITY_LOGON_TYPE)data.LogonType;

          //Look at sectype to see if interactive or remote interactive
          Console.WriteLine(secType.ToString())
          If (secType == SECURITY_LOGON_TYPE.Interactive || secType ==    SECURITY_LOGON_TYPE.RemoteInteractive)
          {
            //do something
          }

       }

       iter = (IntPtr)((int)iter + Marshal.SizeOf(typeof(LUID)));
       //move the pointer forward
       LsaFreeReturnBuffer(sessionData);
       //free the SECURITY_LOGON_SESSION_DATA memory in the struct
  }
  LsaFreeReturnBuffer(luidPtr);       //free the array of LUIDs

这篇关于如何知道 Windows 会话是否是交互式会话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 09:54