2016-08-12 89 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"; 
     } 
    } 
相關問題