2016-08-12 90 views
-1

我正在创建一个将在Citrix上运行的应用程序,并且该应用程序将在多个用户登录的计算机上运行。如何在Citrix系统上获得用户的UNIQUE窗口?

这里是场景:用户A登录到机器1.用户B登录到机器1我们的程序在用户A登录时启动。用户B然后打开任何程序(我们正在监视)并且应该接收一个提问问题的对话框。然而,用户B不是接收到对话,而是用户A获得对话。

如何将父母/对话框显示给正确的用户?

我试过为桌面对话父母,认为每个用户都有自己独特的桌面,但没有奏效。 (见this

任何建议/想法/或例子将不胜感激。

由于

+0

_“我们的程序启动”_ - 在哪里? _“我们正在监控”_ - 怎么样?没有一个好的[mcve],这个问题最好太宽泛。这听起来像你在一个用户的会话中运行你的监控程序;如果您希望在任何用户的会话中显示一个窗口,则需要在每个用户的会话中运行程序,并让每个流程实例只监视在该会话中运行的程序。没有具体细节,不可能完全说出你如何做到这一点。 –

+0

彼得 - 你如何获得用户的会话?那将是一个很好的起点! – user3174075

+0

_“你如何获得用户会话”_ - 这取决于你所说的“会话”。通常,如果要在每个用户的会话中运行程序,只需将该程序配置为每个用户的启动程序即可。您不需要任何访问会话状态本身的权限。程序只在用户登录时运行。如果你想要的东西不是这样,你需要更具体一些,当然要在你对这个主题进行研究时使用它。 –

回答

0

事实证明,在Citrix系统(和Windows操作系统)上,每一个过程是与用户相关联的SID。但是,在设置WMI查询以观察特定进程时,在citrix系统上,我收到了与该进程交互的任何用户的通知。

因此,我的应用程序不仅需要跟踪我感兴趣的过程,还需要跟踪与该过程交互的用户。

这段代码计算出谁拥有的过程:(当然现在缺少的是检测过程中的活动,并呼吁“GetProcessOwnerInformation”的代码,但留给作为练习读者:-))

private ProcessOwnerInformation GetProcessOwnerInformation(uint processId) 
    { 
     WindowsIdentity _user = WindowsIdentity.GetCurrent(); 
     string stringSID = string.Empty; 
     string process = ExGetProcessInfoByPID((int)processId, out stringSID); 

     bool bIgnoreCase = true; 

     ProcessOwnerInformation retval = new ProcessOwnerInformation(); 
     bool bOwnsProcess = string.Compare(stringSID, _user.User.Value, bIgnoreCase) == 0; 
     if(bOwnsProcess) 
     { 
      retval.procID = processId; 
      retval.OwnsProcess = bOwnsProcess; 
      retval.SID = stringSID; 
     } 

     return retval; 
    } 


    public const int TOKEN_QUERY = 0X00000008; 

    const int ERROR_NO_MORE_ITEMS = 259; 

    enum TOKEN_INFORMATION_CLASS 
    { 
     TokenUser = 1, 
     TokenGroups, 
     TokenPrivileges, 
     TokenOwner, 
     TokenPrimaryGroup, 
     TokenDefaultDacl, 
     TokenSource, 
     TokenType, 
     TokenImpersonationLevel, 
     TokenStatistics, 
     TokenRestrictedSids, 
     TokenSessionId 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct TOKEN_USER 
    { 
     public _SID_AND_ATTRIBUTES User; 
    } 


    [StructLayout(LayoutKind.Sequential)] 
    public struct _SID_AND_ATTRIBUTES 
    { 
     public IntPtr Sid; 
     public int Attributes; 
    } 

    [DllImport("advapi32")] 
    static extern bool OpenProcessToken(
     IntPtr ProcessHandle, // handle to process 
     int DesiredAccess, // desired access to process 
     ref IntPtr TokenHandle // handle to open access token 
    ); 

    [DllImport("kernel32")] 
    static extern IntPtr GetCurrentProcess(); 

    [DllImport("advapi32", CharSet = CharSet.Auto)] 
    static extern bool GetTokenInformation(
     IntPtr hToken, 
     TOKEN_INFORMATION_CLASS tokenInfoClass, 
     IntPtr TokenInformation, 
     int tokeInfoLength, 
     ref int reqLength 
    ); 

    [DllImport("kernel32")] 
    static extern bool CloseHandle(IntPtr handle); 

    [DllImport("advapi32", CharSet = CharSet.Auto)] 
    static extern bool ConvertSidToStringSid(
     IntPtr pSID, 
     [In, Out, MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid 
    ); 

    [DllImport("advapi32", CharSet = CharSet.Auto)] 
    static extern bool ConvertStringSidToSid(
     [In, MarshalAs(UnmanagedType.LPTStr)] string pStringSid, 
     ref IntPtr pSID 
    ); 


    public static bool DumpUserInfo(IntPtr pToken, out IntPtr SID) 
    { 
     int Access = TOKEN_QUERY; 
     IntPtr procToken = IntPtr.Zero; 
     bool ret = false; 
     SID = IntPtr.Zero; 
     try 
     { 
      if (OpenProcessToken(pToken, Access, ref procToken)) 
      { 
       ret = ProcessTokenToSid(procToken, out SID); 
       CloseHandle(procToken); 
      } 
      return ret; 
     } 
     catch (Exception err) 
     { 
      return false; 
     } 
    } 

    private static bool ProcessTokenToSid(IntPtr token, out IntPtr SID) 
    { 
     TOKEN_USER tokUser; 
     const int bufLength = 256; 
     IntPtr tu = Marshal.AllocHGlobal(bufLength); 
     bool ret = false; 
     SID = IntPtr.Zero; 
     try 
     { 
      int cb = bufLength; 
      ret = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenUser, tu, cb, ref cb); 
      if (ret) 
      { 
       tokUser = (TOKEN_USER)Marshal.PtrToStructure(tu, typeof(TOKEN_USER)); 
       SID = tokUser.User.Sid; 
      } 
      return ret; 
     } 
     catch (Exception err) 
     { 
      return false; 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(tu); 
     } 
    } 

    public static string ExGetProcessInfoByPID(int PID, out string SID)//, out string OwnerSID) 
    { 
     IntPtr _SID = IntPtr.Zero; 
     SID = String.Empty; 
     try 
     { 
      Process process = Process.GetProcessById(PID); 
      if (DumpUserInfo(process.Handle, out _SID)) 
      { 
       ConvertSidToStringSid(_SID, ref SID); 
      } 
      return process.ProcessName; 
     } 
     catch 
     { 
      return "Unknown"; 
     } 
    } 
相关问题