Windows 从Win32\u NetworkLogin配置文件返回的上次登录错误

Windows 从Win32\u NetworkLogin配置文件返回的上次登录错误,windows,wmi,wmi-query,Windows,Wmi,Wmi Query,使用WMI资源管理器(或任何其他工具),我的用户的LastLogon时间戳显示的是过时的值,而不是当前日期(因为我当前正在使用这台电脑): 同时,其他域用户以LastLogon作为当前日期列出,因此这只是我的用户的问题 另一方面,正在按预期报告当前日期: DOMAIN\user user name 2015/03/10 10:14 WMI错误结果的原因是什么 环境:Win 7 x64,本地管理员组中添加了域用户。我很高兴从NetUsers.exe的Optimium X开发者那里得

使用WMI资源管理器(或任何其他工具),我的用户的
LastLogon
时间戳显示的是过时的值,而不是当前日期(因为我当前正在使用这台电脑):

同时,其他域用户以
LastLogon
作为当前日期列出,因此这只是我的用户的问题

另一方面,正在按预期报告当前日期:

DOMAIN\user    user name    2015/03/10 10:14
WMI错误结果的原因是什么



环境:Win 7 x64,本地管理员组中添加了域用户。

我很高兴从NetUsers.exe的Optimium X开发者那里得到了答案,非常专业,信息量也非常丰富

他们用C++编写程序,最可靠的追踪登录时间的方法是读取位于“HKLM \软件\微软\ Windows NT \ CurrutValp[DrPrimelelist]”/P>的每个配置文件注册表项上的LASTWrWESTE时间。 在我亲自尝试使用WMI的每个类之后,它们都失败了,因此我求助于pInvoke使用C读取隐藏的注册表属性“LastWriteTime”#

以下是您在HKLM注册表项上调用的主要函数:

    private static DateTime GetHKLMRegistryKeyLastWriteTime(RegistryKey key, string RemoteComputer)
    {
        DateTime LastWriteTime = DateTime.MinValue;
        //set RegSAM access
        RegSAM desiredSAM = RegSAM.Read;
        //set key to same navigation (win32 vs win64)
        if (key.View == RegistryView.Registry32)
        {
            desiredSAM |= RegSAM.WOW64_32Key;
        }
        else if(key.View == RegistryView.Registry64)
        {
            desiredSAM |= RegSAM.WOW64_64Key;
        }

        //Get Registry Hive Key on RemoteComputer.
        UIntPtr computerRegHive = ConnectToRegistryHive(RemoteComputer, HKEY_LOCAL_MACHINE);

        if(computerRegHive != UIntPtr.Zero)
        {
            string keyPath = key.Name;
            int rootSeperatorIndex = keyPath.IndexOf(@"\");
            if (rootSeperatorIndex != -1)
            {
                keyPath = keyPath.Substring(rootSeperatorIndex + 1, keyPath.Length - (rootSeperatorIndex + 1));
            }

            UIntPtr computerRegKey = OpenRegistrySubKey(computerRegHive, keyPath, desiredSAM);
            //We no longer need computerRegHive, close!
            RegCloseKey(computerRegHive);
            if(computerRegKey != UIntPtr.Zero)
            {
                LastWriteTime = GetRegistryKeyLastWriteTime(computerRegKey);
                //We no longer need computerRegKey, close!
                RegCloseKey(computerRegKey);
            }
        }
        return LastWriteTime;
    }
以下是使其工作所需的材料:

public static uint HKEY_LOCAL_MACHINE = 0x80000002u;

[DllImport("advapi32.dll")]
private static extern int RegConnectRegistry(string lpmachineName, uint hKey, out UIntPtr phKResult);

[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
private static extern int RegOpenKeyEx(
        UIntPtr hKey,
        string subKey,
        int ulOptions, //Set to 0
        RegSAM samDesired, //Desired Access (win32/win64 & Read or ReadWrite)
        out UIntPtr hkResult);

[DllImport("advapi32.dll")]
private static extern int RegQueryInfoKey(
        UIntPtr hKey,
        StringBuilder lpClass,
        IntPtr lpcbClass,
        IntPtr lpReserved,
        IntPtr lpcSubKeys,
        IntPtr lpcbMaxSubKeyLen,
        IntPtr lpcbMaxClassLen,
        IntPtr lpcValues,
        IntPtr lpcbMaxValueNameLen,
        IntPtr lpcbMaxValueLen,
        IntPtr lpcbSecurityDescriptor,
        [Out][Optional]out FILETIME lpftLastWriteTime
    );

[DllImport("advapi32.dll")]
private static extern int RegCloseKey(UIntPtr hKey);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FileTimeToSystemTime([In] ref FILETIME lpFileTime, out SYSTEMTIME lpSystemTime);

[Flags]
public enum RegSAM
{
    QueryValue = 0x0001,
    SetValue = 0x0002,
    CreateSubKey = 0x0004,
    EnumerateSubKeys = 0x0008,
    Notify = 0x0010,
    CreateLink = 0x0020,
    WOW64_32Key = 0x0200,
    WOW64_64Key = 0x0100,
    WOW64_Res = 0x0300,
    Read = 0x00020019,
    Write = 0x00020006,
    Execute = 0x00020019,
    AllAccess = 0x000f003f
}

    [StructLayout(LayoutKind.Sequential)]
    public struct FILETIME
    {
        public uint LowPart;
        public uint HighPart;
    };

    [StructLayout(LayoutKind.Sequential, Pack = 2)]
    public struct SYSTEMTIME
    {
        public ushort Year;
        public ushort Month;
        public ushort DayOfWeek;
        public ushort Day;
        public ushort Hour;
        public ushort Minute;
        public ushort Second;
        public ushort Milliseconds;

        public SYSTEMTIME(DateTime dt)
        {
            dt = dt.ToUniversalTime();
            Year = Convert.ToUInt16(dt.Year);
            Month = Convert.ToUInt16(dt.Month);
            DayOfWeek = Convert.ToUInt16(dt.DayOfWeek);
            Day = Convert.ToUInt16(dt.Day);
            Hour = Convert.ToUInt16(dt.Hour);
            Minute = Convert.ToUInt16(dt.Minute);
            Second = Convert.ToUInt16(dt.Second);
            Milliseconds = Convert.ToUInt16(dt.Millisecond);
        }

        public SYSTEMTIME(ushort year, ushort month, ushort day, ushort hour = 0, ushort minute = 0, ushort second = 0, ushort millisecond = 0)
        {
            Year = year;
            Month = month;
            Day = day;
            Hour = hour;
            Minute = minute;
            Second = second;
            Milliseconds = millisecond;
            DayOfWeek = 0;
        }

        public static implicit operator DateTime(SYSTEMTIME st)
        {
            if (st.Year == 0 || st == MinValue)
                return DateTime.MinValue;
            if (st == MaxValue)
                return DateTime.MaxValue;
            return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds, DateTimeKind.Utc);
        }

        public static bool operator ==(SYSTEMTIME s1, SYSTEMTIME s2)
        {
            return (s1.Year == s2.Year && s1.Month == s2.Month && s1.Day == s2.Day && s1.Hour == s2.Hour && s1.Minute == s2.Minute && s1.Second == s2.Second && s1.Milliseconds == s2.Milliseconds);
        }

        public static bool operator !=(SYSTEMTIME s1, SYSTEMTIME s2)
        {
            return !(s1 == s2);
        }

        public static readonly SYSTEMTIME MinValue, MaxValue;

        static SYSTEMTIME()
        {
            MinValue = new SYSTEMTIME(1601, 1, 1);
            MaxValue = new SYSTEMTIME(30827, 12, 31, 23, 59, 59, 999);
        }

        public override bool Equals(object obj)
        {
            if (obj is SYSTEMTIME)
                return ((SYSTEMTIME)obj) == this;
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }


    /// <summary>
    /// When a handle returned is no longer needed, it should be closed by calling RegCloseKey.
    /// </summary>
    private static UIntPtr ConnectToRegistryHive(string RemoteComputer, uint hKey)
    {
        UIntPtr computerRegHive = UIntPtr.Zero;
        RegConnectRegistry(@"\\" + RemoteComputer, hKey, out computerRegHive);
        return computerRegHive;
    }

    /// <summary>
    /// When a handle returned is no longer needed, it should be closed by calling RegCloseKey.
    /// </summary>
    private static UIntPtr OpenRegistrySubKey(UIntPtr CurrentHKey, string SubKeyName, RegSAM desiredSAM)
    {
        UIntPtr hRegKey = UIntPtr.Zero;
        RegOpenKeyEx(CurrentHKey, SubKeyName, 0, desiredSAM, out hRegKey);
        return hRegKey;
    }

    private static DateTime GetRegistryKeyLastWriteTime(UIntPtr hKey)
    {
        FILETIME ft = new FILETIME();

        int ret = RegQueryInfoKey(hKey, null, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 
                                  IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out ft);
        if(ret == 0)
        {
            SYSTEMTIME st = new SYSTEMTIME(DateTime.MinValue);
            FileTimeToSystemTime(ref ft, out st);
            //Thanks to a highly developed SYSTEMTIME struct which has a DateTime implicit operator .... it's like magic!
            DateTime LastWriteTime = st;
            return LastWriteTime.ToLocalTime();
        }
        return DateTime.MinValue;
    }
公共静态uint HKEY_本地_机器=0x8000002u;
[DllImport(“advapi32.dll”)]
私有静态extern int RegConnectRegistry(字符串lpmachineName、uint hKey、out uintpttr phKResult);
[DllImport(“advapi32.dll”,CharSet=CharSet.Unicode)]
私有静态外部程序int RegOpenKeyEx(
UIntPtr hKey,
字符串子键,
int-ulOptions,//设置为0
RegSAM samDesired,//所需访问(win32/win64&Read或ReadWrite)
out UIntPtr(香港结果);
[DllImport(“advapi32.dll”)]
私有静态extern int RegQueryInfoKey(
UIntPtr hKey,
StringBuilder类,
IntPtr lpcbClass,
IntPtr LPR保留,
IntPtr LPC子密钥,
IntPtr lpcbMaxSubKeyLen,
IntPtr LPCBMAXSCLASSLEN,
IntPtr LPC值,
IntPtr lpcbMaxValueNameLen,
IntPtr lpcbMaxValueLen,
IntPtr lpcbSecurityDescriptor,
[输出][可选]输出文件时间lpftLastWriteTime
);
[DllImport(“advapi32.dll”)]
专用静态外部注册表项(UIntPtr hKey);
[DllImport(“kernel32.dll”,SetLastError=true)]
私有静态外部bool FileTimeToSystemTime([In]ref FILETIME lpFileTime,out SYSTEMTIME lpSystemTime);
[旗帜]
公共枚举RegSAM
{
QueryValue=0x0001,
设置值=0x0002,
CreateSubKey=0x0004,
枚举子键=0x0008,
通知=0x0010,
CreateLink=0x0020,
WOW64_32Key=0x0200,
WOW64_64Key=0x0100,
WOW64_Res=0x0300,
读取=0x00020019,
写入=0x00020006,
执行=0x00020019,
AllAccess=0x000f003f
}
[StructLayout(LayoutKind.Sequential)]
公共结构文件时间
{
公共部分;
公共部分;
};
[StructLayout(LayoutKind.Sequential,Pack=2)]
公共结构系统时间
{
公共卫生年;
公众健康月;
公众假期;
公众体育日;
公众假期;
公众健康纪录;
公共卫生服务第二;
公共卫生服务;
公共系统时间(日期时间dt)
{
dt=dt.ToUniversalTime();
年=换算成16(dt年);
月=换算为16(dt月);
DayOfWeek=转换为.ToUInt16(dt.DayOfWeek);
日=换算为16(日);
小时=转换时间16(dt小时);
分钟=转换为16分钟(dt分钟);
秒=转换为16(dt秒);
毫秒=Convert.ToUInt16(dt.毫秒);
}
公共系统时间(ushort年、ushort月、ushort日、ushort小时=0、ushort分钟=0、ushort秒=0、ushort毫秒=0)
{
年=年;
月=月;
天=天;
小时=小时;
分钟=分钟;
秒=秒;
毫秒=毫秒;
DayOfWeek=0;
}
公共静态隐式运算符DateTime(SYSTEMTIME st)
{
如果(st.Year==0 | | st==MinValue)
return DateTime.MinValue;
if(st==MaxValue)
return DateTime.MaxValue;
返回新的日期时间(st.Year、st.Month、st.Day、st.Hour、st.Minute、st.Second、st.millizes、DateTimeKind.Utc);
}
公共静态布尔运算符==(系统时间s1,系统时间s2)
{
返回值(s1.Year==s2.Year&&s1.Month==s2.Month&&s1.Day==s2.Day&&s1.Hour==s2.Hour&&s1.Minute==s2.Minute&&s1.Second==s2.Second&&s1.millizes==s2.millizes);
}
公共静态布尔运算符!=(系统时间s1,系统时间s2)
{
返回!(s1==s2);
}
公共静态只读SYSTEMTIME最小值、最大值;
静态系统时间()
{
MinValue=新系统时间(1601,1,1);
MaxValue=新系统时间(30827,12,31,23,59,59999);
}
公共覆盖布尔等于(对象对象对象)
{
if(obj是系统时间)
返回((系统时间)obj)=此;
返回基数等于(obj);
}
公共覆盖int GetHashCode()
{
返回base.GetHashCode();
}
}
/// 
///当不再需要返回的句柄时,应通过调用RegCloseKey将其关闭。
/// 
专用静态UIntPtr ConnectToRegistryHive(字符串远程计算机,uint hKey)
{
uintpttr computerRegHive=uintpttr.Zero;
RegConnectRegistry(@“\\”+远程计算机、hKey、out computerRegHive);
返回计算机配置单元;
}
/// 
///当不再需要返回的句柄时,应通过调用RegCloseKey将其关闭。
/// 
私有静态UIntPtr OpenRegistrySubKey(UINTPTTR CurrentHKey,字符串S
public static uint HKEY_LOCAL_MACHINE = 0x80000002u;

[DllImport("advapi32.dll")]
private static extern int RegConnectRegistry(string lpmachineName, uint hKey, out UIntPtr phKResult);

[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
private static extern int RegOpenKeyEx(
        UIntPtr hKey,
        string subKey,
        int ulOptions, //Set to 0
        RegSAM samDesired, //Desired Access (win32/win64 & Read or ReadWrite)
        out UIntPtr hkResult);

[DllImport("advapi32.dll")]
private static extern int RegQueryInfoKey(
        UIntPtr hKey,
        StringBuilder lpClass,
        IntPtr lpcbClass,
        IntPtr lpReserved,
        IntPtr lpcSubKeys,
        IntPtr lpcbMaxSubKeyLen,
        IntPtr lpcbMaxClassLen,
        IntPtr lpcValues,
        IntPtr lpcbMaxValueNameLen,
        IntPtr lpcbMaxValueLen,
        IntPtr lpcbSecurityDescriptor,
        [Out][Optional]out FILETIME lpftLastWriteTime
    );

[DllImport("advapi32.dll")]
private static extern int RegCloseKey(UIntPtr hKey);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FileTimeToSystemTime([In] ref FILETIME lpFileTime, out SYSTEMTIME lpSystemTime);

[Flags]
public enum RegSAM
{
    QueryValue = 0x0001,
    SetValue = 0x0002,
    CreateSubKey = 0x0004,
    EnumerateSubKeys = 0x0008,
    Notify = 0x0010,
    CreateLink = 0x0020,
    WOW64_32Key = 0x0200,
    WOW64_64Key = 0x0100,
    WOW64_Res = 0x0300,
    Read = 0x00020019,
    Write = 0x00020006,
    Execute = 0x00020019,
    AllAccess = 0x000f003f
}

    [StructLayout(LayoutKind.Sequential)]
    public struct FILETIME
    {
        public uint LowPart;
        public uint HighPart;
    };

    [StructLayout(LayoutKind.Sequential, Pack = 2)]
    public struct SYSTEMTIME
    {
        public ushort Year;
        public ushort Month;
        public ushort DayOfWeek;
        public ushort Day;
        public ushort Hour;
        public ushort Minute;
        public ushort Second;
        public ushort Milliseconds;

        public SYSTEMTIME(DateTime dt)
        {
            dt = dt.ToUniversalTime();
            Year = Convert.ToUInt16(dt.Year);
            Month = Convert.ToUInt16(dt.Month);
            DayOfWeek = Convert.ToUInt16(dt.DayOfWeek);
            Day = Convert.ToUInt16(dt.Day);
            Hour = Convert.ToUInt16(dt.Hour);
            Minute = Convert.ToUInt16(dt.Minute);
            Second = Convert.ToUInt16(dt.Second);
            Milliseconds = Convert.ToUInt16(dt.Millisecond);
        }

        public SYSTEMTIME(ushort year, ushort month, ushort day, ushort hour = 0, ushort minute = 0, ushort second = 0, ushort millisecond = 0)
        {
            Year = year;
            Month = month;
            Day = day;
            Hour = hour;
            Minute = minute;
            Second = second;
            Milliseconds = millisecond;
            DayOfWeek = 0;
        }

        public static implicit operator DateTime(SYSTEMTIME st)
        {
            if (st.Year == 0 || st == MinValue)
                return DateTime.MinValue;
            if (st == MaxValue)
                return DateTime.MaxValue;
            return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds, DateTimeKind.Utc);
        }

        public static bool operator ==(SYSTEMTIME s1, SYSTEMTIME s2)
        {
            return (s1.Year == s2.Year && s1.Month == s2.Month && s1.Day == s2.Day && s1.Hour == s2.Hour && s1.Minute == s2.Minute && s1.Second == s2.Second && s1.Milliseconds == s2.Milliseconds);
        }

        public static bool operator !=(SYSTEMTIME s1, SYSTEMTIME s2)
        {
            return !(s1 == s2);
        }

        public static readonly SYSTEMTIME MinValue, MaxValue;

        static SYSTEMTIME()
        {
            MinValue = new SYSTEMTIME(1601, 1, 1);
            MaxValue = new SYSTEMTIME(30827, 12, 31, 23, 59, 59, 999);
        }

        public override bool Equals(object obj)
        {
            if (obj is SYSTEMTIME)
                return ((SYSTEMTIME)obj) == this;
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }


    /// <summary>
    /// When a handle returned is no longer needed, it should be closed by calling RegCloseKey.
    /// </summary>
    private static UIntPtr ConnectToRegistryHive(string RemoteComputer, uint hKey)
    {
        UIntPtr computerRegHive = UIntPtr.Zero;
        RegConnectRegistry(@"\\" + RemoteComputer, hKey, out computerRegHive);
        return computerRegHive;
    }

    /// <summary>
    /// When a handle returned is no longer needed, it should be closed by calling RegCloseKey.
    /// </summary>
    private static UIntPtr OpenRegistrySubKey(UIntPtr CurrentHKey, string SubKeyName, RegSAM desiredSAM)
    {
        UIntPtr hRegKey = UIntPtr.Zero;
        RegOpenKeyEx(CurrentHKey, SubKeyName, 0, desiredSAM, out hRegKey);
        return hRegKey;
    }

    private static DateTime GetRegistryKeyLastWriteTime(UIntPtr hKey)
    {
        FILETIME ft = new FILETIME();

        int ret = RegQueryInfoKey(hKey, null, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 
                                  IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out ft);
        if(ret == 0)
        {
            SYSTEMTIME st = new SYSTEMTIME(DateTime.MinValue);
            FileTimeToSystemTime(ref ft, out st);
            //Thanks to a highly developed SYSTEMTIME struct which has a DateTime implicit operator .... it's like magic!
            DateTime LastWriteTime = st;
            return LastWriteTime.ToLocalTime();
        }
        return DateTime.MinValue;
    }