2009-03-16 3 views

ответ

60

Here is where I found the answer.

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

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

[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. 
+4

написать обычную C++/CLI-оболочку и introcuding другой сборке проще, чем написать структуру из 9 строк? – Lucas

+4

Пространство имен Microsoft.VisualStudio.Shell.Interop содержит определенную структуру SYSTEMTIME; см. http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.systemtime.aspx –

+0

Только не позволяйте Marc Gravell видеть вашу структуру! ;-) – si618

7
  1. PInvoke вызвать Win32 API SetSystemTime (example)
  2. классы System.Management с классом WMI Win32_OperatingSystem и вызвать SetDateTime по этому классу.

Оба требуют, чтобы вызывающему абоненту был предоставлен SeSystemTimePrivilege и эта привилегия включена.

14

Вы можете использовать вызов команды DOS, но вызов функции в окнах 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); 
} 
4

Поскольку я упомянул об этом в комментарии, вот 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); 
+0

Я пробовал свой код, но он не работает. https://gist.github.com/jtara1/07cfd5ebffab8296564f86000c50510e В любом случае, я нашел решение, которое хотел, и проверил его https://github.com/jtara1/MiscScripts/blob/00a5d330d784d7e423c0f8a83172ddfc31aad3fa/MiscScripts/UpdateOSTime.cs –

8

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

  1. На Windows Vista, 7, 8 OS это требует контроля учетных записей для того, чтобы получить необходимые права администратора для успешного выполнения функции SetSystemTime. Причина в том, что для процесса вызова требуется привилегия SE_SYSTEMTIME_NAME.
  2. Функция 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); 
+0

I не могу напрямую изменить системное время с помощью этого –

+0

Я успешно использовал этот код для нескольких проектов. Вы используете исполняемый файл как администратор? В противном случае этот код, безусловно, не сработает. –

+1

ничего себе это решило мою проблему. Проблема в том, что часовой пояс для вашего местного времени мешает получить правильное время, поэтому строка «DateTime dateTime = tempDateTime.ToUniversalTime();» решил все это. –

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");

+0

Вот протестированный, готовый скомпилировать и запустить версию вашего кода https://github.com/jtara1/MiscScripts/blob/master/MiscScripts/UpdateOSTime.cs Мне пришлось пройти как минимум 4 stackoverflow для этого, поскольку я не знакомы с C# или этими lib. –

-2

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(); 
    } 
} 
+0

тот же ответ, который вы дали ... –

Смежные вопросы