Comment puis-je modifier la date et l'heure du système local par programme avec C #?
Voici où j'ai trouvé la réponse.
Je l'ai republié ici pour améliorer la clarté.
Définissez cette structure:
[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;
}
Ajoutez la méthode extern
suivante à votre classe:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetSystemTime(ref SYSTEMTIME st);
Appelez ensuite la méthode avec une instance de votre structure comme ceci:
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.
Vous pouvez utiliser un appel à une commande DOS, mais l'invocation de la fonction dans la DLL Windows est une meilleure façon de le faire.
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);
}
De nombreux points de vue et approches sont déjà là, mais voici quelques spécifications qui sont actuellement laissées de côté et qui, selon moi, pourraient trébucher et dérouter certaines personnes.
SetSystemTime
. La raison en est que le processus appelant a besoin du privilège SE_SYSTEMTIME_NAME .SetSystemTime
attend une structure SYSTEMTIME
en temps universel coordonné (UTC) . Sinon, cela ne fonctionnera pas comme souhaité.Selon où/comment vous obtenez vos valeurs DateTime
, il peut être préférable de le jouer en toute sécurité et d'utiliser ToUniversalTime()
avant de définir les valeurs correspondantes dans le SYSTEMTIME
struct.
Exemple de code:
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);
Les deux nécessitent que l'appelant se soit vu accorder SeSystemTimePrivilege et que ce privilège soit activé.
tilisez cette fonction pour changer l'heure du système (testé dans la fenêtre 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();
}
}
Exemple:Appel dans la méthode de chargement du formulaire setDate ("5-6-92"); setTime ("2: 4: 5 AM");
Depuis que je l'ai mentionné dans un commentaire, voici un wrapper 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);
}
};
}
Le code client C # est désormais très simple:
JDanielSmith.Utilities.SetSystemTime(DateTime.Now);
Faites attention!. Si vous supprimez la propriété inutilisée de la structure, elle définit l'heure incorrecte. J'ai perdu 1 jour à cause de cela. Je pense que l'ordre de la structure est important.
C'est la bonne structure:
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;
};
Si vous exécutez SetSystemTime (), cela fonctionne comme prévu. Pour le test, j'ai réglé l'heure comme ci-dessous;
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);
L'heure réglée: 15.10.2019 10:20, c'est ok.
Mais je supprime la propriété DayOfWeek qui n'est pas utilisée;
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);
Exécuter le même code mais l'heure réglée sur: 10.10.2019 20:
Veuillez faire attention à l'ordre et à tous les champs de la structure SystemTime. Yusuf