web-dev-qa-db-fra.com

Modifier la date système par programme

Comment puis-je modifier la date et l'heure du système local par programme avec C #?

52
Yoann. B

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.
82
Andrew Hare

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);
}  
15
MarmouCorp

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.

  1. Sur Windows Vista, 7, 8 OS cela nécessite une invite UAC afin d'obtenir les droits administratifs nécessaires pour exécuter correctement la fonction SetSystemTime. La raison en est que le processus appelant a besoin du privilège SE_SYSTEMTIME_NAME .
  2. La fonction 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); 
12
Derek W
  1. PInvoke pour appeler Win32 API SetSystemTime, (exemple)
  2. Classes System.Management avec la classe WMI Win32_OperatingSystem et appelez SetDateTime sur cette classe.

Les deux nécessitent que l'appelant se soit vu accorder SeSystemTimePrivilege et que ce privilège soit activé.

7
Avram

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

6
Hiren Raiyani

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);
3
Ðаn

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

0
Yusuf GURDAG