Получение даты перевода часов. - C#
Формулировка задачи:
Здравствуйте, не получается получить правильный день перевода часов на летнее/стандартное время через WinAPI. Месяц возвращается верный, а день — нет.
GetTimeZoneInformation
SetTimeZoneInfomation
public static TimeZoneInformation GetTimeZoneInformation() { var tzi = new TimeZoneInformation(); Kernel.GetTimeZoneInformation(ref tzi); // Установка параметров перевода (по докам MSDN) tzi.StandardDate.wHour = 3; tzi.StandardDate.wDayOfWeek = 4; tzi.StandardDate.wMonth = 10; tzi.StandardDate.wDay = 4; tzi.DaylightDate.wHour = 2; tzi.DaylightDate.wDayOfWeek = 0; tzi.DaylightDate.wMonth = 4; tzi.DaylightDate.wDay = 3; // Сохранение данных перевода. WinAPI.SetTimeZoneInfomation(tzi); var info = new TimeZoneInformation(); Kernel.GetTimeZoneInformation(ref info); // Структура с данными перевода часов. return info; } public static void SetTimeZoneInfomation(TimeZoneInformation tzi) { // Установка привилегий. var tkp = new TOKEN_PRIVILEGES { PrivilegeCount = 1, Privileges = new LUID_AND_ATTRIBUTES[1] { new LUID_AND_ATTRIBUTES { Attributes = SE_PRIVILEGE_ENABLED } } }; var hToken = new IntPtr(); Advapi.OpenProcessToken(Advapi.GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken); Advapi.LookupPrivilegeValue("", SE_TIME_ZONE_NAME, out tkp.Privileges[0].Luid); Advapi.AdjustTokenPrivileges(hToken, false, ref tkp, 0, IntPtr.Zero, IntPtr.Zero); // Установка даты. Kernel.SetTimeZoneInformation(ref tzi); // Сброс привилегий. tkp.Privileges[0].Attributes = 0; Advapi.AdjustTokenPrivileges(hToken, false, ref tkp, 0, IntPtr.Zero, IntPtr.Zero); } class Kernel { [DllImport("kernel32.dll", SetLastError = true)] public static extern uint GetTimeZoneInformation(ref TimeZoneInformation lpTimeZoneInformation); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern bool SetTimeZoneInformation(ref TimeZoneInformation lpTimeZoneInformation); } class Advapi { [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, int BufferLength, IntPtr PreviousState, IntPtr ReturnLength); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle); [DllImport("kernel32.dll")] public static extern IntPtr GetCurrentProcess(); [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid); }
Решение задачи: «Получение даты перевода часов.»
textual
Листинг программы
using System; using System.ComponentModel; using System.Runtime.InteropServices; namespace Test { class Program { struct SYSTEMTIME { public ushort wYear; public ushort wMonth; public ushort wDayOfWeek; public ushort wDay; public ushort wHour; public ushort wMinute; public ushort wSecond; public ushort wMilliseconds; } [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Unicode )] struct TIME_ZONE_INFORMATION { public int Bias; [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 32 )] public string StandardName; public SYSTEMTIME StandardDate; public int StandardBias; [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 32 )] public string DaylightName; public SYSTEMTIME DaylightDate; public int DaylightBias; } [DllImport( "kernel32.dll", SetLastError = true )] static extern uint GetTimeZoneInformation ( out TIME_ZONE_INFORMATION lpTimeZoneInformation ); [DllImport( "kernel32.dll", SetLastError = true )] [return: MarshalAs( UnmanagedType.Bool )] static extern bool SetTimeZoneInformation ( ref TIME_ZONE_INFORMATION lpTimeZoneInformation ); public static void Main ( ) { Privileges.Enable( "SeTimeZonePrivilege" ); TIME_ZONE_INFORMATION tzi; int err = 0; GetTimeZoneInformation( out tzi ); tzi.StandardDate.wHour = 3; tzi.StandardDate.wDayOfWeek = 4; tzi.StandardDate.wMonth = 10; tzi.StandardDate.wDay = 4; tzi.DaylightDate.wHour = 2; tzi.DaylightDate.wDayOfWeek = 0; tzi.DaylightDate.wMonth = 4; tzi.DaylightDate.wDay = 3; if ( !SetTimeZoneInformation( ref tzi ) ) throw new Win32Exception( err = Marshal.GetLastWin32Error() ); GetTimeZoneInformation( out tzi ); // Меняется, при первом использовании, потом ясное дело - нет. Debugger.Break(); } } class Privileges { [StructLayout( LayoutKind.Sequential, Pack = 1 )] struct TOKEN_PRIVILEGES { public uint PrivilegeCount; public long Luid; public uint Attributes; } [DllImport( "advapi32.dll", SetLastError = true )] [return: MarshalAs( UnmanagedType.Bool )] static extern bool AdjustTokenPrivileges ( IntPtr htok, bool disall, ref TOKEN_PRIVILEGES newst, int len, IntPtr prev, IntPtr relen ); [DllImport( "kernel32.dll", SetLastError = true )] static extern IntPtr GetCurrentProcess ( ); [DllImport( "advapi32.dll", SetLastError = true )] [return: MarshalAs( UnmanagedType.Bool )] static extern bool OpenProcessToken ( IntPtr h, int acc, ref IntPtr phtok ); [DllImport( "advapi32.dll", SetLastError = true )] [return: MarshalAs( UnmanagedType.Bool )] static extern bool LookupPrivilegeValue ( string host, string name, ref long pluid ); const int SE_PRIVILEGE_ENABLED = 0x00000002; const int TOKEN_QUERY = 0x00000008; const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; [DllImport( "kernel32.dll", SetLastError = true )] [return: MarshalAs( UnmanagedType.Bool )] static extern bool CloseHandle ( IntPtr hObject ); public static bool Enable ( string PrivName ) { TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES(); IntPtr hToken = IntPtr.Zero; bool retVal = false; if ( !OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref hToken ) ) return false; if ( LookupPrivilegeValue( null, PrivName, ref tp.Luid ) ) { tp.PrivilegeCount = 1; tp.Attributes = SE_PRIVILEGE_ENABLED; retVal = AdjustTokenPrivileges( hToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero ); } CloseHandle( hToken ); return false; } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д