Получение даты перевода часов. - 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;
        }
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.714 из 5
Похожие ответы