Вопрос

Как я могу программно изменить дату и время локальной системы с помощью C #?

Это было полезно?

Решение

Здесь я нашел ответ.

Я разместил его здесь, чтобы улучшить ясность.

Определите эту структуру:

[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
    public short wYear;
    public short wMonth;
    public short wDayOfWeek;
    public short wDay;
    public short wHour;
    public short wMinute;
    public short wSecond;
    public short wMilliseconds;
}

Добавьте следующий метод extern в свой класс:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetSystemTime(ref SYSTEMTIME st);

Затем вызовите метод с экземпляром вашей структуры следующим образом:

SYSTEMTIME st = new SYSTEMTIME();
st.wYear = 2009; // must be short
st.wMonth = 1;
st.wDay = 1;
st.wHour = 0;
st.wMinute = 0;
st.wSecond = 0;

SetSystemTime(ref st); // invoke this method.

Другие советы

Вы можете использовать вызов команды DOS, но вызов этой функции в Windows DLL - лучший способ сделать это.

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)]
public extern static void Win32GetSystemTime(ref SystemTime sysTime);

[DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
public extern static bool Win32SetSystemTime(ref SystemTime sysTime);

private void button1_Click(object sender, EventArgs e)
{
    // Set system date and time
    SystemTime updatedTime = new SystemTime();
    updatedTime.Year = (ushort)2009;
    updatedTime.Month = (ushort)3;
    updatedTime.Day = (ushort)16;
    updatedTime.Hour = (ushort)10;
    updatedTime.Minute = (ushort)0;
    updatedTime.Second = (ushort)0;
    // Call the unmanaged function that sets the new date and time instantly
    Win32SetSystemTime(ref updatedTime);
}  

Многие отличные точки зрения и подходы уже здесь, но вот некоторые спецификации, которые в настоящее время опущены, и я думаю, что они могут сбить с толку и запутать некоторых людей.

<Ол>
  • В ОС Windows Vista, 7, 8 для этого потребуется запрос UAC, чтобы получить необходимые административные права для успешного выполнения функции SetSystemTime. Причина в том, что вызывающему процессу нужна привилегия SE_SYSTEMTIME_NAME .
  • Функция SYSTEMTIME ожидает структуру DateTime по согласованному универсальному времени (UTC) . В противном случае это не будет работать так, как хотелось бы.
  • В зависимости от того, где и как вы получаете ваши значения ToUniversalTime(), может быть лучше не рисковать и использовать <=> перед установкой соответствующих значений в <=> структуре.

    Пример кода:

    DateTime tempDateTime = GetDateTimeFromSomeService();
    DateTime dateTime = tempDateTime.ToUniversalTime();
    
    SYSTEMTIME st = new SYSTEMTIME();
    // All of these must be short
    st.wYear = (short)dateTime.Year;
    st.wMonth = (short)dateTime.Month;
    st.wDay = (short)dateTime.Day;
    st.wHour = (short)dateTime.Hour;
    st.wMinute = (short)dateTime.Minute;
    st.wSecond = (short)dateTime.Second;
    
    // invoke the SetSystemTime method now
    SetSystemTime(ref st); 
    
    <Ол>
  • PInvoke для вызова Win32 API SetSystemTime, ( пример )
  • Классы System.Management с WMI-классом Win32_OperatingSystem и вызов SetDateTime для этого класса.
  • Оба требуют, чтобы вызывающему абоненту был предоставлен SeSystemTimePrivilege и чтобы эта привилегия была включена.

    Используйте эту функцию для изменения системного времени (протестировано в window 8).

     void setDate(string dateInYourSystemFormat)
        {
            var proc = new System.Diagnostics.ProcessStartInfo();
            proc.UseShellExecute = true;
            proc.WorkingDirectory = @"C:\Windows\System32";
            proc.CreateNoWindow = true;
            proc.FileName = @"C:\Windows\System32\cmd.exe";
            proc.Verb = "runas";
            proc.Arguments = "/C date " + dateInYourSystemFormat;
            try
            {
                System.Diagnostics.Process.Start(proc);
            }
            catch
            {
                MessageBox.Show("Error to change time of your system");
                Application.ExitThread();
            }
        }
    void setTime(string timeInYourSystemFormat)
        {
            var proc = new System.Diagnostics.ProcessStartInfo();
            proc.UseShellExecute = true;
            proc.WorkingDirectory = @"C:\Windows\System32";
            proc.CreateNoWindow = true;
            proc.FileName = @"C:\Windows\System32\cmd.exe";
            proc.Verb = "runas";
            proc.Arguments = "/C time " + timeInYourSystemFormat;
            try
            {
                System.Diagnostics.Process.Start(proc);
            }
            catch
            {
                MessageBox.Show("Error to change time of your system");
                Application.ExitThread();
            }
        }
    

    Пример: Вызов метода загрузки формы Установленная дата ("5-6-92");Время захода солнца ("2:4:5 утра");

    Поскольку я упоминал об этом в комментарии, вот оболочка C ++ / CLI:

    #include <windows.h>
    namespace JDanielSmith
    {
        public ref class Utilities abstract sealed /* abstract sealed = static */
        {
        public:
            CA_SUPPRESS_MESSAGE("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")
            static void SetSystemTime(System::DateTime dateTime) {
                LARGE_INTEGER largeInteger;
                largeInteger.QuadPart = dateTime.ToFileTimeUtc(); // "If your compiler has built-in support for 64-bit integers, use the QuadPart member to store the 64-bit integer."
    
    
                FILETIME fileTime; // "...copy the LowPart and HighPart members [of LARGE_INTEGER] into the FILETIME structure."
                fileTime.dwHighDateTime = largeInteger.HighPart;
                fileTime.dwLowDateTime = largeInteger.LowPart;
    
    
                SYSTEMTIME systemTime;
                if (FileTimeToSystemTime(&fileTime, &systemTime))
                {
                    if (::SetSystemTime(&systemTime))
                        return;
                }
    
    
                HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
                throw System::Runtime::InteropServices::Marshal::GetExceptionForHR(hr);
            }
        };
    }
    

    Код клиента C # теперь очень прост:

    JDanielSmith.Utilities.SetSystemTime(DateTime.Now);
    

    Будьте осторожны! Если вы удаляете неиспользуемое свойство из структуры, оно устанавливает неправильное время. Я потерял 1 день из-за этого. Я думаю, что порядок структуры важен.

    Это правильная структура:

    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;
    
            };
    

    Если вы запускаете SetSystemTime (), он работает как положено. Для теста я установил время, как показано ниже;

    SystemTime st = new SystemTime();
    st.Year = 2019;
    st.Month = 10;
    st.Day = 15;
    st.Hour = 10;
    st.Minute = 20;
    st.Second = 30;
    
    SetSystemTime(ref st);
    

    Установлено время: 15.10.2019 10:20, все в порядке.

    Но я удаляю свойство DayOfWeek, которое не используется;

    public struct SystemTime
                {
                    public ushort Year;
                    public ushort Month;
                    public ushort Day;
                    public ushort Hour;
                    public ushort Minute;
                    public ushort Second;
                    public ushort Millisecond;
    
                };
    
    SystemTime st = new SystemTime();
        st.Year = 2019;
        st.Month = 10;
        st.Day = 15;
        st.Hour = 10;
        st.Minute = 20;
        st.Second = 30;
    
        SetSystemTime(ref st);
    

    Запустите тот же код, но установите время: 10.10.2019 20:30

    Пожалуйста, будьте внимательны, порядок и все поля структуры SystemTime. Юсуф

      

    proc.Arguments = " / C Дата: " + dateInYourSystemFormat;

    Это рабочая функция:

    void setDate(string dateInYourSystemFormat)
    {
        var proc = new System.Diagnostics.ProcessStartInfo();
        proc.UseShellExecute = true;
        proc.WorkingDirectory = @"C:\Windows\System32";
        proc.CreateNoWindow = true;
        proc.FileName = @"C:\Windows\System32\cmd.exe";
        proc.Verb = "runas";
        proc.Arguments = "/C Date:" + dateInYourSystemFormat;
        try
        {
            System.Diagnostics.Process.Start(proc);
        }
        catch
        {
            MessageBox.Show("Error to change time of your system");
            Application.ExitThread();
        }
    }
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top