Получение даты перевода часов. - 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;
- }
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д