Как я могу изменить локальную системную дату и время программно с помощью С#?
Изменение системной даты программно
Ответ 1
Я перепробовал его здесь, чтобы улучшить ясность.
Определите эту структуру:
[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.
Ответ 2
Вы можете использовать вызов для команды DOS, но вызов функции в dll windows - лучший способ сделать это.
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);
}
Ответ 3
Много замечательных точек зрения и подходов уже есть здесь, но вот некоторые спецификации, которые в настоящее время не учтены, и что я чувствую, что мог бы поработать и смутить некоторых людей.
- В Windows Vista, 7, 8 OS для этого потребуется запросить UAC, чтобы получить необходимые права администратора для успешного выполнения функции
SetSystemTime
. Причина в том, что для процесса вызова требуется привилегия SE_SYSTEMTIME_NAME. - Функция
SetSystemTime
ожидает структуруSYSTEMTIME
в скоординированном универсальном времени (UTC). В противном случае он не будет работать по-другому.
В зависимости от того, где/как вы получаете свои значения DateTime
, лучше всего безопасно играть и ToUniversalTime()
до устанавливая соответствующие значения в структуре SYSTEMTIME
.
Пример кода:
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);
Ответ 4
- PInvoke для вызова Win32 API SetSystemTime, (пример)
- классы System.Management с классом WMI Win32_OperatingSystem и вызовите SetDateTime в этом классе.
Оба требуют, чтобы вызывающему было предоставлено SeSystemTimePrivilege и эта привилегия включена.
Ответ 5
Используйте эту функцию для изменения времени системы (проверено в окне 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();
}
}
Пример: Вызов в режиме загрузки формы SETDATE ( "5-6-92" ); setTime ( "2: 4: 5 AM" );
Ответ 6
Так как я упомянул об этом в комментарии, здесь обертка С++/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);
}
};
}
Клиентский код С# теперь очень прост:
JDanielSmith.Utilities.SetSystemTime(DateTime.Now);
Ответ 7
Быть осторожен!. Если вы удаляете неиспользуемое свойство из структуры, оно устанавливает неправильное время. Я потерял 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. Юсуф
Ответ 8
proc.Arguments = "/C Date:" + 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();
}
}