2012-11-21 21 views
0

我正在處理需要監視Windows會話更改的服務應用程序,並在特定用戶登錄時自動啓動應用程序。從會話ID獲取完整的Windows域名

下面是它是如何工作的,我有一個文件,其中包含以用戶主體名稱格式([email protected])存儲的Windows用戶名列表。我的服務將監視任何會話更改,並在用戶登錄後採取特定操作。

List<string> _UsersList; 
object _sessionCheckLock = new object(); 
     void OnCheckSession(int nSessionId, bool bIsLoggIn) 
     { 
      lock(_sessionCheckLock) 
      { 
       try 
       { 
        string sUserName = string.Empty; 
        string sDomain = string.Empty; 

        IntPtr pUserName = IntPtr.Zero; 
        uint nBytesReturned = 0; 
        if (WTSQuerySessionInformation(IntPtr.Zero, (uint)nSessionId, WTS_INFO_CLASS.WTSUserName, out pUserName, out nBytesReturned) && (pUserName != IntPtr.Zero)) 
        { 
         sUserName = Marshal.PtrToStringAnsi(pUserName); 

         WTSFreeMemory(pUserName); 

         IntPtr pDomain = IntPtr.Zero; 
         if(WTSQuerySessionInformation(IntPtr.Zero, (uint)nSessionId, WTS_INFO_CLASS.WTSDomainName, out pDomain, out nBytesReturned) && (pDomain != IntPtr.Zero)) 
         { 
          sDomain = Marshal.PtrToStringAnsi(pDomain); 
          WTSFreeMemory(pDomain); 
         } 
         else 
         { 

         } 

         if (!string.IsNullOrEmpty(sUserName)) 
         { 
          if(!string.IsNullOrEmpty(sDomain) 
          { 
           sUserName += "@" + sDomain; 
          } 

          foreach(string username in _UsersList) 
          { 
           if(string.Compare(sUsername, username, true)==0) 
           { 
           //Do a couple of things 
           return; 
           } 
          } 

         } 
        } 
        else 
        { 
         return; 
        } 
       } 
       catch (System.Exception ex) 
       { 

       } 
      } 
     } 

上面的代碼是我每次引發新登錄事件時調用的函數。 _UsersList是包含服務允許使用的所有用戶名的字符串列表。 這裏的問題是WTSQuerySessionInformationWTS_INFO_CLASS.WTSDomainName一起使用時不會返回域的全名,因此比較失敗。例如,如果在用戶列表中存在名爲([email protected])的用戶名並且登錄,則查詢會話的域名,它只返回沒有.LOCAL附錄的(DOMAIN)。我需要找到一種方法來獲取完整的域名以匹配我的列表中的域名。

有人可以幫助請

回答

2

看看Cassia.Net,這是一個非常有用的。

你可以下載源代碼,我用這個項目,我必須讓所有用戶登錄到服務器。

決明子 .NET Windows終端服務/遠程桌面服務庫

http://code.google.com/p/cassia/

希望幫助

+0

謝謝,這有很大的幫助。 –

1

WTSDomainName顯示用戶〜的是我無法找到任何明確的文檔所屬的域,但我認爲它越來越NetBIOS名稱,而不是FQDN。您應該可以使用這兩個環境變量USERDNSDOMAIN USERDOMAIN來保存這些值。

您還可以使用ADSI做了較爲詳細的查找,看看線程here

但所有這一切說,除非你有一個非常複雜的森林結構,用戶在許多不同的領域登錄樹......只要將轉換硬編碼到您的應用中,速度可能會更快。它們不是經常改變的,而且從新域登錄的用戶也應該很少。

1

紅蛇,也決明子真的有用嗎?我和你有同樣的問題,但是Cassia似乎在底下使用了相同的WTSQuerySessionInformation調用,所以我仍然只能得到短域名。

this頁面我找到了DsGetDcName函數的參考,我可以使用WTSQuerySessionInformation給我的短域名獲得FQDN。這裏是我的例子,適用於我:

std::wstring GetSessionDomainName(DWORD sessionId) 
{ 
    std::wstring domainName; 
    LPWSTR buffer = NULL; 
    DWORD bufferSize = 0; 

    if(WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSDomainName, &buffer, &bufferSize)) 
    { 
     PDOMAIN_CONTROLLER_INFOW domainControllerInfo = NULL; 
     DWORD retVal = DsGetDcNameW(NULL, buffer, NULL, NULL, DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME, &domainControllerInfo); 
     if (retVal == 0) 
      domainName = domainControllerInfo->DnsForestName; 

     WTSFreeMemory(buffer); 
     NetApiBufferFree(domainControllerInfo); 
    } 

    return domainName; 
} 
+0

[pInvoke版本](http://www.pinvoke.net/default.aspx/netapi32/dsgetdcname.html) – rifaco