[問題]使用WTS來查詢使用者登入的資訊

看板C_and_CPP (C/C++)作者 (Jay)時間5年前 (2019/11/14 19:28), 5年前編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
開發平台(Platform): (Ex: Win10, Linux, ...) Win10 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) vs2019 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) C#是使用Cassia C++目前沒有 問題(Question): 各位大大好,在下目前公司需要我做個新功能, 要能讓系統抓取AD網域內各台電腦的使用者帳戶登入的資訊 基本的:session id、網域名稱、電腦名稱、登入時間、連線狀態 在下有兩個狀況想要詢問一下 1.使用WTSQuerySessionInformation來查詢帳號登入的資訊 如下圖1是使用query session的方式來找尋,希望可以顯示的是這樣 https://imgur.com/ppZbKRR
但我目前只能顯示session id、所在的網域群組、使用者名稱 還差了登入時間與登入狀態 (明明用了WTSLogonTime與WTSConnectState)還是不給顯示.... 餵入的資料(Input): (目前都先輸入在程式碼內) 預期的正確結果(Expected Output): 類似這樣:(1.47是網域內其中一台電腦) https://imgur.com/BflG7gE
錯誤結果(Wrong Output): 我把此程式碼放入到1.47內執行的結果: https://imgur.com/KVQWlsK
程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔) #include <Windows.h> #include <vector> #include <string> #include <iostream> #include <WtsApi32.h> #include <tchar.h> #pragma comment(lib, "WtsApi32.lib") using namespace std; // typedef std::basic_string<TCHAR> tstring; //Get current sessions bool EnumSessionIds(std::vector<DWORD>& list) { list.clear(); WTS_SESSION_INFO* pSI = NULL; DWORD dwSICount; BOOL bRes = WTSEnumerateSessions(WTS_CURRENT_SERVER,0,1,&pSI,&dwSICount); if(bRes==0) return false; for (unsigned int i = 0; i < dwSICount; i++) list.push_back(pSI[i].SessionId); WTSFreeMemory(pSI); return true; } //Get Username from session id bool GetSessionUserName(DWORD dwSessionID,tstring& username) { LPTSTR pBuffer = NULL; DWORD dwBufferLen; bool bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionID, WTSUserName, &pBuffer, &dwBufferLen); if (bRes == FALSE) return false; username = pBuffer; WTSFreeMemory(pBuffer); return true; } //Get domain name from session id bool GetSessionDomain(DWORD dwSessionID,tstring& domain_name) { LPTSTR pBuffer = NULL; DWORD dwBufferLen; bool bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionID, WTSDomainName, &pBuffer, &dwBufferLen); if (bRes == false) return false; domain_name = pBuffer; WTSFreeMemory(pBuffer); return true; } // Get ConnectState from session id bool GetConnectState(DWORD dwSessionID, tstring& ConnectState) { LPTSTR pBuffer = NULL; DWORD dwBufferLen; bool bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionID, WTSConnectState, &pBuffer, &dwBufferLen); if (bRes == false) return false; ConnectState = pBuffer; WTSFreeMemory(pBuffer); return true; } //Get LogonTime from session id bool GetLogonTime(DWORD dwSessionID, tstring& logontime) { LPTSTR pBuffer = NULL; DWORD dwBufferLen; bool bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionID, WTSLogonTime, &pBuffer, &dwBufferLen); if (bRes == false) return false; logontime = pBuffer; WTSFreeMemory(pBuffer); return true; } //int _tmain(int argc, _TCHAR* argv[]) int main() { //顯示電腦端的使用者帳戶的session id列表 std::vector<DWORD> sessionIds; bool bRes = EnumSessionIds(sessionIds); if (!bRes) { // error return 0; } // enum sessions-> session列表,透過vector顯示 std::vector<DWORD>::iterator iter; for (iter = sessionIds.begin(); iter != sessionIds.end(); iter++) { cout << "-------------------------------------------------------" << endl; int sessionid = *iter; cout << "Session ID= "<< sessionid << endl; // print session domain tstring domain; GetSessionDomain(*iter, domain); _tprintf(_T("Session Domain = %s\n"), domain.c_str()); //cout << "Session Domain = "<<domain.c_str() << endl; // print session username tstring username; GetSessionUserName(*iter, username); _tprintf(_T("Session UserName = %s\n"), username.c_str()); //cout << "Session UserName = " << username.c_str() << endl; //print session ConnectState tstring connectstate; GetConnectState(*iter,connectstate); _tprintf(_T("Connectstate = %s\n"), connectstate.c_str()); //print session LogonTime tstring logontime; GetLogonTime(*iter, logontime); _tprintf(_T("Login Time = \n"), logontime.c_str()); cout << "-------------------------------------------------------" << endl; } system("PAUSE"); return 0; } 補充說明(Supplement): 目前還有一個問題: 如果使用此API:WTS,可以像我這樣輸入ip的方式,顯示AD網域內 要查詢的電腦IP,他目前有登入的使用者資訊嗎? 如下圖,這是我用C#搭配DLL-Cassia做出來的, 備註:若要透過AD網域內其中一台電腦(網域內隨便一台PC或是Serve也可以) 查詢其他/全部電腦,需要擁有AD網域的管理者權限帳戶,才可以查詢 https://imgur.com/PxWoBym
但公司要求系統需要用C++的程式來跑 (強調需要用WTS),可以這樣做嗎? 如果不行,是否得要加入其他DLL之類的? 還是有其他方式? 公司提出第一個方式就是這樣,在AD Server上直接透過此程式碼與API, 直接把每台電腦的資訊回傳到Server內,這樣系統可以直接呈現資訊。 我是想到的第二個方式比較麻煩:撰寫C++的Windows Service程式, 並透過派送給每一台電腦,讓每台電腦產生一個log檔案,再讓系統去抓取此log檔案 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 218.161.102.123 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1573730901.A.2AE.html ※ 編輯: jayzhuang (218.161.102.123 臺灣), 11/14/2019 19:29:44
文章代碼(AID): #1TpJfLAk (C_and_CPP)
文章代碼(AID): #1TpJfLAk (C_and_CPP)