Wie kann ich Datum und Uhrzeit des lokalen Systems mit C # programmgesteuert ändern?
Hier habe ich die Antwort gefunden.
Ich habe es hier neu veröffentlicht, um die Übersichtlichkeit zu verbessern.
Definieren Sie diese Struktur:
[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;
}
Fügen Sie Ihrer Klasse die folgende extern
Methode hinzu:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetSystemTime(ref SYSTEMTIME st);
Rufen Sie dann die Methode mit einer Instanz Ihrer Struktur wie folgt auf:
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.
Sie können einen Aufruf eines DOS-Befehls verwenden, aber der Aufruf der Funktion in der Windows-DLL ist eine bessere Möglichkeit, dies zu tun.
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);
}
Es gibt bereits viele großartige Sichtweisen und Ansätze, aber hier sind einige Spezifikationen, die derzeit ausgelassen werden und die meines Erachtens einige Leute verwirren könnten.
SetSystemTime
erfolgreich aus. Der Grund dafür ist, dass der aufrufende Prozess die Berechtigung SE_SYSTEMTIME_NAME benötigt.SetSystemTime
erwartet eine SYSTEMTIME
-Struktur in der koordinierten Weltzeit (UTC) . Andernfalls funktioniert es nicht wie gewünscht.Abhängig davon, wo und wie Sie Ihre DateTime
Werte erhalten, ist es möglicherweise am besten, auf Nummer sicher zu gehen und ToUniversalTime()
zu verwenden, bevor Sie die entsprechenden Werte in SYSTEMTIME
struct.
Codebeispiel:
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);
Beides setzt voraus, dass dem Aufrufer das SeSystemTimePrivilege erteilt wurde und dieses Privileg aktiviert ist.
Verwenden Sie diese Funktion, um die Uhrzeit des Systems zu ändern (getestet in Fenster 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();
}
}
Beispiel:Methode zum Laden des Formulars aufrufen setDate ("5-6-92"); setTime ("2: 4: 5 AM");
Da ich es in einem Kommentar erwähnt habe, ist hier ein C++/CLI-Wrapper:
#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);
}
};
}
Der C # -Clientcode ist jetzt sehr einfach:
JDanielSmith.Utilities.SetSystemTime(DateTime.Now);
Achtung!. Wenn Sie nicht verwendete Eigenschaften aus der Struktur löschen, wird die Uhrzeit falsch eingestellt. Ich habe 1 Tag dadurch verloren. Ich denke, die Reihenfolge der Struktur ist wichtig.
Das ist die richtige Struktur:
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;
};
Wenn Sie das SetSystemTime () ausführen, funktioniert es erwartet. Zum Testen stelle ich die Zeit wie folgt ein;
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);
Die eingestellte Zeit: 15.10.2019 10:20, ist ok.
Aber ich lösche DayOfWeek-Eigenschaft, die nicht verwendet wird;
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);
Führen Sie den gleichen Code aus, aber die Uhrzeit wurde eingestellt auf: 10.10.2019 20:
Bitte beachten Sie die Reihenfolge und alle Felder der SystemTime-Struktur. Yusuf