2009-02-06 7 views
8

Je suis en train de mettre à jour mon temps de système en utilisant les éléments suivants:Comment mettre à jour la date du système et/ou du temps en utilisant .NET

[StructLayout(LayoutKind.Sequential)] 
private struct SYSTEMTIME 
{ 
    public ushort wYear; 
    public ushort wMonth; 
    public ushort wDayOfWeek; 
    public ushort wDay; 
    public ushort wHour; 
    public ushort wMinute; 
    public ushort wSecond; 
    public ushort wMilliseconds; 
} 

[DllImport("kernel32.dll", EntryPoint = "GetSystemTime", SetLastError = true)] 
private extern static void Win32GetSystemTime(ref SYSTEMTIME lpSystemTime); 

[DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)] 
private extern static bool Win32SetSystemTime(ref SYSTEMTIME lpSystemTime); 

public void SetTime() 
{ 
    TimeSystem correctTime = new TimeSystem(); 
    DateTime sysTime = correctTime.GetSystemTime(); 
    // Call the native GetSystemTime method 
    // with the defined structure. 
    SYSTEMTIME systime = new SYSTEMTIME(); 
    Win32GetSystemTime(ref systime); 

    // Set the system clock ahead one hour. 
    systime.wYear = (ushort)sysTime.Year; 
    systime.wMonth = (ushort)sysTime.Month; 
    systime.wDayOfWeek = (ushort)sysTime.DayOfWeek; 
    systime.wDay = (ushort)sysTime.Day; 
    systime.wHour = (ushort)sysTime.Hour; 
    systime.wMinute = (ushort)sysTime.Minute; 
    systime.wSecond = (ushort)sysTime.Second; 
    systime.wMilliseconds = (ushort)sysTime.Millisecond; 

    Win32SetSystemTime(ref systime); 
} 

Quand je déboguer tout semble bon et toutes les valeurs sont correctes, mais quand il appelle le Win32SetSystemTime (ref systime) l'heure réelle du système (heure d'affichage) ne change pas et reste la même. La partie étrange est que quand j'appelle le Win32GetSystemTime (réf systime) il me donne la nouvelle heure mise à jour. Quelqu'un peut-il me donner de l'aide à ce sujet?

+0

que je vois, TimeSystem est non de la classe de système de base, êtes-vous sûr que TimeSystem ne change pas la temps? essayez de commenter le Win32SetSystemTime (ref systime); line – Avram

Répondre

4

Selon le code que vous avez ici, vous n'augmentez pas l'heure. Il semble que vous définissez l'heure de votre système exactement au même moment que lorsque vous avez appelé Win32GetSystemTime.

Essayez:

systime.wHour = (ushort)(sysTime.Hour + 1); 
+0

Mais je ne veux pas incrémenter l'heure. Je veux le mettre à une autre heure. – user62958

+0

Le commentaire de code dans votre code indique spécifiquement "mettre l'horloge système en avance d'une heure". Vous ne changez pas votre temps système simplement parce que vous ne le changez pas. Pour le définir à une autre heure, vous devez définir la structure que vous envoyez dans la méthode à une heure différente de l'heure actuelle. –

6

Une partie de votre problème est que vous avez deux ou trois signatures PInvoke incorrectes. Le plus notable SetSystemTime devrait avoir une valeur de retour non-vide. Voici la signature correcte

/// Return Type: BOOL->int 
    ///lpSystemTime: SYSTEMTIME* 
    [System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="SetSystemTime")] 
    [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] 
public static extern bool SetSystemTime([InAttribute()] ref SYSTEMTIME lpSystemTime) ; 

Je soupçonne que la serrure d'une valeur de retour foiré la pile et la fonction SetSystemTime essentiellement fini avec les mauvaises données.

2
 

TimeSpan diffLocalTime = DateTime.Now - DateTime.UtcNow; 
SystemTime systemTime = new SystemTime(); 
systemTime.Second = ... 
systemTime.Minute =.... 
systemTime.Hour -= (ushort)(diffLocalTime.Hours + 1); // 00:59:59 I rounded as 1 hour 
bool result = SetSystemTime(ref systemTime); 
 

Ceci en utilisant Cela fonctionne correctement pour le fuseau horaire local.

1
[DllImport("Kernel32.dll")] 
public static extern bool SetLocalTime(ref StractData.Datetime.SYSTEMTIME Time); 
0

Vous avez juste un problème de privilèges, quand je lance ce programme sans privilèges, il does'nt change la date, mais si je fais un clic droit sur le programme et cliquez sur Exécuter en tant qu'administrateur, il fonctionne!

2

Pas besoin de P/Invoke - il existe un moyen plus simple (mais pas très connu) disponible à partir de l'assembly Microsoft.VisualBasic. Si vous êtes en C#, n'oubliez pas d'ajouter une référence à celui-ci.

Vous pouvez utiliser la classe Microsoft.VisualBasic.DateAndTime pour obtenir et modifier la date ou l'heure. Les propriétés Today et TimeOfDay ont des paramètres qui effectueront les modifications à la date ou à l'heure.

Vous avez toujours besoin des privilèges appropriés - reportez-vous au lien de documentation MSDN ci-dessous.

Voici un exemple arbitraire pour modifier le temps:

public static void SetTimeToPast() 
{ 
    Microsoft.VisualBasic.DateAndTime.TimeOfDay = DateTime.Now.AddMinutes(-2); 
} 

Référence sur MSDN: http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.dateandtime(v=vs.110).aspx

+0

Pour moi, changer la date du système Microsoft.VisualBasic.DateAndTime.TimeOfDay.Today = [date nouvelle] a fait l'affaire. Merci beaucoup. C'est jusqu'à présent la solution la plus simple et la plus propre. – FrenkyB

+0

L'utilisation de Win32SetSystemTime fonctionne pour moi, mais malheureusement, cela ne fonctionne pas. – Matt

Questions connexes