Измените системное время программно, используя datetimepeaker

Я пытаюсь изменить системную дату и время, используя следующий код С#. Но в результате в системной дате не происходит никаких изменений (ошибка также не возникает). Я также попытался раскомментировать закомментированную часть кода. Но никакого эффекта. :( После этого я попытался изменить время из командной строки (не используя С#). Затем он показал: «Клиент не имеет требуемой привилегии». Я знаю, что это сообщение может не иметь никакого отношения к коду, но я добавляю его чтобы прояснить мою ситуацию.

   [StructLayout(LayoutKind.Sequential)]
      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 Millisecond;
     }
    /*
            [DllImport("kernel32.dll", EntryPoint = "GetSystemTime", SetLastError = true)]
            [return: MarshalAsAttribute(UnmanagedType.Bool)]
            public static extern bool Win32GetSystemTime([InAttribute]ref Systemtime sysTime);
     */
    [DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
    [return: MarshalAsAttribute(UnmanagedType.Bool)]
    public static extern bool Win32SetSystemTime([InAttribute]ref Systemtime sysTime);

    private void DateTimeSelectedButton_Click(object sender, EventArgs e)
    {
        //var neededtime = MonthChangePhenomenonDateTimePicker.Value - TimeSpan.FromHours(5)-TimeSpan.FromMinutes(30);
        // Set system date and time

        Systemtime updatedTime = new Systemtime();
        updatedTime.Year = (ushort)MonthChangePhenomenonDateTimePicker.Value.Year;
        updatedTime.Month = (ushort)MonthChangePhenomenonDateTimePicker.Value.Month;
        updatedTime.Day = (ushort)MonthChangePhenomenonDateTimePicker.Value.Day;

        // UTC time; it will be modified according to the regional settings of the target computer so the actual hour might differ
        updatedTime.Hour = (ushort)MonthChangePhenomenonDateTimePicker.Value.Hour;
        updatedTime.Minute = (ushort)MonthChangePhenomenonDateTimePicker.Value.Minute;
        updatedTime.Second = (ushort)MonthChangePhenomenonDateTimePicker.Value.Second;
        // Call the unmanaged function that sets the new date and time instantly
        Win32SetSystemTime(ref updatedTime);

        MessageBox.Show(@"You Have Current System Time: " + updatedTime);
    }

Пожалуйста, помогите мне узнать, что происходит не так. Заранее спасибо. :)


person Rajib Majumdar    schedule 15.10.2016    source источник
comment
Измените Win32SetSystemTime на SetSystemTime, а затем попробуйте.   -  person vivek nuna    schedule 15.10.2016
comment
Только что попробовал @vivek nuna, но безрезультатно :(   -  person Rajib Majumdar    schedule 15.10.2016
comment
запустите свой код от имени администратора, а затем попробуйте   -  person vivek nuna    schedule 15.10.2016
comment
Как это сделать!? @вивек нуна   -  person Rajib Majumdar    schedule 15.10.2016
comment
напишите, нажмите на визуальную студию, вы увидите запуск от имени администратора   -  person vivek nuna    schedule 15.10.2016
comment
Вау, вивек нуна, я не могу поверить, что это сработало. Да, но как запускать код от имени администратора в каждом случае (программно)   -  person Rajib Majumdar    schedule 15.10.2016
comment
нет, это просто означает, что у вас должны быть на это права. Но запускать программу от имени администратора тоже вредно. так что вы должны быть осторожны.   -  person vivek nuna    schedule 15.10.2016
comment
Как заставить программу получить права? запросить разрешение у пользователя в случае необходимости. :)   -  person Rajib Majumdar    schedule 15.10.2016
comment
поищите как запустить процесс от имени администратора в интернете. вы получите представление.   -  person vivek nuna    schedule 15.10.2016
comment
@RajibMajumdar: вы можете добавить файл манифеста, чтобы любое приложение Windows запускалось от имени администратора. В файле манифеста поместите это значение <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />   -  person GauravKP    schedule 16.10.2016


Ответы (2)


Далее следует консольное приложение C# для поднятия SE_SYSTEMTIME_NAME на основе сообщения «C# — Как включить SeDebugPrivilege?" из блога Tri Nguyen и протестирована на моем ноутбуке с 64-разрядной версией Windows 7. Пожалуйста, не забудьте оставить комментарий в этом блоге.

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr GetCurrentProcess();

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CloseHandle(IntPtr hHandle);

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID
        {
            public UInt32 LowPart;
            public Int32 HighPart;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct TOKEN_PRIVILEGES
        {
            public UInt32 PrivilegeCount;
            public LUID Luid;
            public UInt32 Attributes;
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool OpenProcessToken(IntPtr ProcessHandle,
            UInt32 DesiredAccess, out IntPtr TokenHandle);

        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
            out LUID lpLuid);

        // Use this signature if you do not want the previous state
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
           [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
           ref TOKEN_PRIVILEGES NewState,
           UInt32 Zero,
           IntPtr Null1,
           IntPtr Null2);

        private static uint TOKEN_QUERY = 0x0008;
        private static uint TOKEN_ADJUST_PRIVILEGES = 0x0020;

        public const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;

        public const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";

        static void Main(string[] args)
        {
            IntPtr hToken;
            string sSEPrivilegeName = SE_SYSTEMTIME_NAME;
            LUID luidSEPrivilegeNameValue;
            TOKEN_PRIVILEGES tkpPrivileges;

            if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken))
            {
                Console.WriteLine("OpenProcessToken() failed, error = {0}. {1} is not available", Marshal.GetLastWin32Error(), sSEPrivilegeName);
                return;
            }
            else
            {
                Console.WriteLine("OpenProcessToken() successfully");
            }

            if (!LookupPrivilegeValue(null, SE_SYSTEMTIME_NAME, out luidSEPrivilegeNameValue))
            {
                Console.WriteLine("LookupPrivilegeValue() failed, error = {0}. {1} is not available", Marshal.GetLastWin32Error(), sSEPrivilegeName);
                CloseHandle(hToken);
                return;
            }
            else
            {
                Console.WriteLine("LookupPrivilegeValue() successfully");
            }

            tkpPrivileges.PrivilegeCount = 1;
            tkpPrivileges.Luid = luidSEPrivilegeNameValue;
            tkpPrivileges.Attributes = SE_PRIVILEGE_ENABLED;

            if (!AdjustTokenPrivileges(hToken, false, ref tkpPrivileges, 0, IntPtr.Zero, IntPtr.Zero))
            {
                Console.WriteLine("LookupPrivilegeValue() failed, error = {0}. {1} is not available", Marshal.GetLastWin32Error(), sSEPrivilegeName);
            }
            else
            {
                Console.WriteLine("{0} is now available", sSEPrivilegeName);
            }
            CloseHandle(hToken);
            Console.ReadLine();
        }
    }
}
person J. Piquard    schedule 16.10.2016

Перед вызовом функции «SetSystemTime» необходимо повысить привилегию SE_SYSTEMTIME_NAME с помощью функции «AdjustTokenPrivileges». Эта функция находится в Advapi32.dll.

person J. Piquard    schedule 15.10.2016
comment
Привет, Дж. Пикард, спасибо за ответ. Но я понятия не имею, как его использовать. Я видел кое-какую документацию, но ни одна из них не помогла. :( Не могли бы вы предоставить какой-нибудь пример кода. Для С#. Для этой проблемы я планирую решить ее с помощью файла манифеста. Еще раз спасибо. - person Rajib Majumdar; 16.10.2016