2010-03-21 4 views
0

J'ai du mal à faire fonctionner SetSystemTime dans mon code C#. SetSystemtime est une fonction kernel32.dll. J'utilise P/invoke (interop) pour l'appeler. SetSystemtime renvoie false et l'erreur est "Paramètre non valide". J'ai posté le code ci-dessous. Je souligne que GetSystemTime fonctionne très bien. J'ai testé cela sur Vista et Windows 7. Sur la base de certains affichages de groupes de discussion, j'ai vu que j'ai désactivé l'UAC. Aucune différence. J'ai fait quelques recherches pour ce problème. J'ai trouvé ce lien: http://groups.google.com.tw/group/microsoft.public.dotnet.framework.interop/browse_thread/thread/805fa8603b00c267Je n'arrive pas à faire en sorte que SetSystemTime fonctionne sous Windows Vista en utilisant C# avec Interop (P/Invoke)

où le problème est signalé mais aucune résolution ne semble être trouvée. Notez que l'UAC est également mentionné mais je ne suis pas sûr que ce soit le problème. Notez également que ce monsieur ne reçoit pas Win32Error réel.

  1. Quelqu'un peut-il essayer mon code sous XP?
  2. Quelqu'un peut-il me dire ce que je fais mal et comment le réparer. Si la réponse est de modifier en quelque sorte les paramètres d'autorisation, j'ai besoin d'un exemple. J'aurais pensé que désactiver l'UAC devrait couvrir cela cependant.
  3. Je ne suis pas obligé d'utiliser cette méthode particulière (SetSystemTime). J'essaie juste d'introduire une «dérive de l'horloge» pour tester quelque chose. S'il y a une autre façon de le faire, dites-le moi s'il vous plaît. Franchement, je suis surpris de devoir utiliser Interop pour changer l'heure du système. J'aurais pensé qu'il existe une méthode .NET.

Nous vous remercions de votre aide ou de vos idées. Andrew

code:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace SystemTimeInteropTest 
{ 
    class Program 
    { 
     #region ClockDriftSetup 
     [StructLayout(LayoutKind.Sequential)] 
     public struct SystemTime 
     { 
      [MarshalAs(UnmanagedType.U2)] 
      public short Year; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Month; 
      [MarshalAs(UnmanagedType.U2)] 
      public short DayOfWeek; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Day; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Hour; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Minute; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Second; 
      [MarshalAs(UnmanagedType.U2)] 
      public short Milliseconds; 
     } 

     [DllImport("kernel32.dll")] 
     public static extern void GetLocalTime(
     out SystemTime systemTime); 

     [DllImport("kernel32.dll")] 
     public static extern void GetSystemTime(
     out SystemTime systemTime); 

     [DllImport("kernel32.dll", SetLastError = true)] 
     public static extern bool SetSystemTime(
     ref SystemTime systemTime); 

     //[DllImport("kernel32.dll", SetLastError = true)] 
     //public static extern bool SetLocalTime(
     //ref SystemTime systemTime); 
     [System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint = "SetLocalTime")] 
     [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] 
     public static extern bool SetLocalTime([InAttribute()] ref SystemTime lpSystemTime); 



     #endregion ClockDriftSetup 
     static void Main(string[] args) 
     { 
      try 
      { 
      SystemTime sysTime; 
      GetSystemTime(out sysTime); 
       sysTime.Milliseconds += (short)80; 
       sysTime.Second += (short)3000; 
       bool bResult = SetSystemTime(ref sysTime); 

       if (bResult == false) 
        throw new System.ComponentModel.Win32Exception(); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Drift Error: " + ex.Message); 
      } 
     } 
    } 
} 
+0

En tant que conseil, vous pouvez utiliser le bouton 101010 dans l'éditeur pour mettre en forme un bloc code. – itowlson

+0

Encore une question de suivi pour les débutants. À un certain moment après que j'ai réussi à avancer l'horloge (voir la réponse de Gabe pour savoir comment le faire), l'horloge revient à l'heure correcte. Je suis toujours en train de rassembler des données sur combien de temps il attend pour faire cela, mais je suppose qu'il est en quelque sorte mis à jour via le réseau ou quelque chose. Quelqu'un sait s'il y a un programme/service Windows qui fait cela? Y at-il un moyen de l'éteindre à des fins de test? Ou est déconnecté du réseau de la manière préférée? Merci beaucoup, Andrew – Dave

Répondre

6

Il existe une méthode .Net pour régler l'heure; ce n'est pas disponible en C# par défaut. Si vous ajoutez une référence à Microsoft.VisualBasic à votre projet, vous pouvez simplement écrire:

Microsoft.VisualBasic.DateAndTime.TimeOfDay = DateTime.Now.AddSeconds(3000).AddMilliseconds(80); 
+0

gabe, Merci beaucoup pour votre réponse. Cela a fonctionné pour moi! – Dave

+0

Une autre question de suivi pour les débutants. À un certain moment après que j'ai réussi à avancer l'horloge (voir la réponse de Gabe pour savoir comment le faire), l'horloge revient à l'heure correcte.Je suis toujours en train de rassembler des données sur combien de temps il attend pour faire cela, mais je suppose qu'il est en quelque sorte mis à jour via le réseau ou quelque chose. Quelqu'un sait s'il y a un programme/service Windows qui fait cela? Y at-il un moyen de l'éteindre à des fins de test? Ou est déconnecté du réseau de la manière préférée? Merci beaucoup, Andrew – Dave

+0

Les chances sont que vous devez arrêter le service 'w32time'. – Gabe

0

Vous ne pouvez simplement ajouter 3000 au champ secondes. Vous devez spécifier un nombre de secondes compris entre 0 et 60. Vous devez ajuster les secondes, les minutes, les heures, les champs etc afin qu'ils soient tous dans une plage valide.

Modifier La façon la plus simple serait en fait d'appeler SystemTimeToFileTime puis ajoutez numSeconds * 10000 à la valeur qu'il donne en arrière, puis appelez FileTimeToSystemTime de se reconvertir à un SystemTime.

+0

codeka, Merci pour la réponse. Je n'ai pas jugé nécessaire de modifier le code ci-dessus (voir la réponse de Gabe). Autrement dit, j'ai ajouté 3600 secondes et l'horloge semble avancer d'une heure. Je ne suis pas sûr si je vous ai mal compris ... – Dave

Questions connexes