我正在尝试获取当前的用户上次login。 我可能是这届本届会议,也可能是之前的会议。
我打电话GetUserName()获取当前的用户名。 我将其馈送到NetUserGetInfo()中以尝试获取上次login时间。 这一切都失败,错误2221(用户未find)。 当我用“pipe理员”尝试它的作品。 即使我硬编码我的用户名,它会返回一个2221.这就是我正在使用的:
nStatus = NetUserGetInfo(NULL, L"administrator", dwLevel, (LPBYTE *) & pBuf);
你怎么能得到当前用户的最后login时间?
谢谢,代码总是欢迎。
这是我目前使用的完整代码:
DWORD dwLevel = 2; NET_API_STATUS nStatus; LPTSTR sStringSid = NULL; LPUSER_INFO_0 pBuf = NULL; LPUSER_INFO_2 pBuf2 = NULL; WCHAR UserName[256]; DWORD nUserName = sizeof(UserName); if(GetUserName(UserName, &nUserName)) { printf("information for %ls\n", UserName); nStatus = NetUserGetInfo(NULL, UserName, dwLevel, (LPBYTE *) & pBuf); if (nStatus == NERR_Success) { pBuf2 = (LPUSER_INFO_2) pBuf; printf("\tUser account name: %ls\n", pBuf2->usri2_name); printf("\tLast logon (seconds since January 1, 1970 GMT): %d\n", pBuf2->usri2_last_logon); printf("\tLast logoff (seconds since January 1, 1970 GMT): %d\n", pBuf2->usri2_last_logoff); } else fprintf(stderr, "NetUserGetinfo failed with error: %d\n", nStatus); if (pBuf != NULL) NetApiBufferFree(pBuf); }
您可以尝试使用其他级别为2例如11。
您也可以尝试使用LsaGetLogonSessionData
(请参阅http://msdn.microsoft.com/zh-cn/library/aa378290.aspx )。 结构SECURITY_LOGON_SESSION_DATA
有很多可以帮助你的信息。 LUID
( LsaGetLogonSessionData
的第一个参数)可以使用TokenStatistics
从GetTokenInformation
获得,并获得TOKEN_STATISTICS
结构的AuthenticationId
字段。
更新 :我更仔细地阅读你的代码,我现在看到你的主要错误。 函数NetUserGetInfo
是非常古老的。 它存在于Windows NT 3.1之前的时间。 微软现在命名为“网络管理”的功能组名称为“LAN Manager API”。 所有功能都是在没有本地登录的情况下引入的。 所以你可以使用NetUserGetInfo
和NULL作为域控制器上的第一个参数。 因此,在使用域帐户登录的情况下,应该调用NetGetDCName
, NetGetAnyDCName
或更好的DsGetDcName
来获取域控制器的名称,并使用该名称(以两个反斜杠开始)作为NetUserGetInfo
的第一个参数。 如果您使用本地工作站帐户登录您的程序应该工作,但帐户似乎我必须是像L“管理员”而不是“管理员”的UNICODE字符串 。 顺便说一下,如果我在本地Windows 7 64位计算机上登录您的程序工作没有任何问题。 代码
nStatus = NetUserGetInfo(NULL, L"administrator", dwLevel, (LPBYTE *) & pBuf);
作品也。
我重复一下,在我看来,获取用户上次登录的最佳方式是使用LSA(本地安全机构)API,如LsaGetLogonSessionData
。 如何承诺我给你写了一个代码示例,它演示了如何在C中使用LsaGetLogonSessionData
:
#include <windows.h> #include <Ntsecapi.h> #include <Sddl.h> #include <tchar.h> #include <stdio.h> //#include <ntstatus.h> #include <malloc.h> #include <strsafe.h> #pragma comment (lib, "Secur32.lib") #pragma comment (lib, "strsafe.lib") // The following constant may be defined by including NtStatus.h. #ifndef STATUS_SUCCESS #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #endif // The LSA authentication functions are available in Unicode only. BOOL GetLogonLUID (LUID *pLuid) { BOOL bSuccess; HANDLE hThread = NULL; DWORD cbReturnLength; TOKEN_STATISTICS ts; __try { bSuccess = OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hThread); // TOKEN_QUERY_SOURCE if (!bSuccess) __leave; cbReturnLength = sizeof(TOKEN_STATISTICS); bSuccess = GetTokenInformation (hThread, TokenStatistics, &ts, sizeof(TOKEN_STATISTICS), &cbReturnLength); if (bSuccess) *pLuid = ts.AuthenticationId; } __finally { if (hThread) CloseHandle (hThread); } return bSuccess; } void PrintUnicodeString (LPCTSTR pszPrefix, LSA_UNICODE_STRING lsaString) { if (lsaString.MaximumLength >= lsaString.Length + sizeof(WCHAR) && lsaString.Buffer[lsaString.Length/sizeof(WCHAR)] == L'\0') _tprintf (TEXT("%s: %ls\n"), pszPrefix, lsaString.Buffer); else if (lsaString.Length <= STRSAFE_MAX_CCH * sizeof(TCHAR)) { LPWSTR sz = (LPWSTR) _alloca (lsaString.Length + sizeof(WCHAR)); StringCbCopyNW (sz, lsaString.Length + sizeof(WCHAR), lsaString.Buffer, lsaString.Length); _tprintf (TEXT("%s: %ls\n"), pszPrefix, sz); } } void PrintLogonType (SECURITY_LOGON_TYPE type) { if (type < Interactive || type > CachedUnlock) // This is used to specify an undefied logon type _tprintf (TEXT("LogonType: UndefinedLogonType\n")); else { static LPTSTR szTypes[] = { TEXT("Interactive"), // Interactively logged on (locally or remotely) TEXT("Network"), // Accessing system via network TEXT("Batch"), // Started via a batch queue TEXT("Service"), // Service started by service controller TEXT("Proxy"), // Proxy logon TEXT("Unlock"), // Unlock workstation TEXT("NetworkCleartext"), // Network logon with cleartext credentials TEXT("NewCredentials"), // Clone caller, new default credentials TEXT("RemoteInteractive"), // Remote, yet interactive. Terminal server TEXT("CachedInteractive"), // Try cached credentials without hitting the net. // The types below only exist in Windows server 2003 and greater TEXT("CachedRemoteInteractive"), // Same as RemoteInteractive, this is used internally for auditing purpose TEXT("CachedUnlock") // Cached Unlock workstation }; _tprintf (TEXT("LogonType: %s\n"), szTypes[(int)type-Interactive]); } } void PrintFilefime (LPCTSTR pszPrefix, const FILETIME *lpFileTime) { SYSTEMTIME st; FILETIME ft; BOOL bSuccess; TCHAR szTime[1024], szDate[1024]; bSuccess = FileTimeToLocalFileTime (lpFileTime, &ft); if (!bSuccess) return; bSuccess = FileTimeToSystemTime (&ft, &st); if (!bSuccess) return; if (GetDateFormat (LOCALE_USER_DEFAULT, // or LOCALE_CUSTOM_UI_DEFAULT DATE_SHORTDATE, &st, NULL, szDate, sizeof(szDate)/sizeof(TCHAR)) > 0) { if (GetTimeFormat (LOCALE_USER_DEFAULT, // or LOCALE_CUSTOM_UI_DEFAULT 0, &st, NULL, szTime, sizeof(szTime)/sizeof(TCHAR)) > 0) { _tprintf (TEXT("%s: %s, %s\n"), pszPrefix, szDate, szTime); } } } int main() { LUID LogonLuid; // LOGONID_CURRENT PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL; LPWSTR pszSid = NULL; NTSTATUS ntStatus; GetLogonLUID (&LogonLuid); __try { ntStatus = LsaGetLogonSessionData (&LogonLuid, &pLogonSessionData); if (ntStatus == STATUS_SUCCESS) { if (pLogonSessionData->UserName.Length) PrintUnicodeString (TEXT("UserName"), pLogonSessionData->UserName); if (pLogonSessionData->LogonDomain.Length) PrintUnicodeString (TEXT("LogonDomain"), pLogonSessionData->LogonDomain); if (pLogonSessionData->AuthenticationPackage.Length) PrintUnicodeString (TEXT("AuthenticationPackage"), pLogonSessionData->AuthenticationPackage); PrintLogonType ((SECURITY_LOGON_TYPE)pLogonSessionData->LogonType); _tprintf (TEXT("Session: %d\n"), pLogonSessionData->Session); if (ConvertSidToStringSidW (pLogonSessionData->Sid, &pszSid)) _tprintf (TEXT("Sid: %ls\n"), pszSid); if (pLogonSessionData->LogonTime.QuadPart) PrintFilefime (TEXT("LogonTime"), (const FILETIME *)&pLogonSessionData->LogonTime); if (pLogonSessionData->Logonserver.Length) PrintUnicodeString (TEXT("Logonserver"), pLogonSessionData->Logonserver); if (pLogonSessionData->DnsDomainName.Length) PrintUnicodeString (TEXT("DnsDomainName"), pLogonSessionData->DnsDomainName); if (pLogonSessionData->Upn.Length) PrintUnicodeString (TEXT("Upn"), pLogonSessionData->Upn); // one can dump more information like HomeDirectory, ProfilePath and so on // if _WIN32_WINNT >= 0x0600 and user login a domain } } __finally { if (pLogonSessionData) LsaFreeReturnBuffer(pLogonSessionData); if (pszSid) pszSid = (LPTSTR)LocalFree (pszSid); } }