2010-10-19 9 views
7

Estoy portando una aplicación desde Windows 2000 (no pregunto) a Windows 7 y necesito replicar la funcionalidad que permite al usuario establecer la hora desde una GUI. Anteriormente, esto se había hecho con una llamada directamente a 'hora' utilizando el símbolo del sistema, pero parece que los permisos de usuario han cambiado un poco en Windows 7.Configuración de la hora programáticamente en Windows 7

Después de haber investigado un poco, parece que puede establecer la hora utilizando un llame al kernel32.dll método Win32SetSystemTime, pero se produce el mismo problema de permisos. Leyendo MSDN Creo que necesito habilitar SE_SYSTEMTIME_NAME, sin embargo, no importa lo que intento, parece que no puedo hacer que esto funcione.

¿Alguien tiene algún código de ejemplo probado para Windows 7 para permitir una llamada API a Win32SetSystemTime?

+0

Yup. Cambia el tiempo, pero no acepta la Zona horaria ... –

Respuesta

7

No sé por qué no está trabajando para usted. El siguiente código establece la hora de hoy a las 4:12 PM UTC. (A mí me funcionó)

public class Program 
{ 
    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 = "SetSystemTime", SetLastError = true)] 
    public extern static bool Win32SetSystemTime(ref SystemTime st); 

    public static void Main(string[] args) 
    { 
     SystemTime st = new SystemTime 
     { 
      Year = 2010, Month = 10, Day = 18, Hour = 16, Minute = 12, DayOfWeek = 1 
     }; 
    } 
} 

De acuerdo con la docs:

El proceso de llamada debe tener el privilegio SE_SYSTEMTIME_NAME. Este privilegio está deshabilitado por defecto. La función SetSystemTime habilita el privilegio SE_SYSTEMTIME_NAME antes de cambiar la hora del sistema y deshabilita el privilegio antes de volver. Para obtener más información, vea Ejecutar con privilegios especiales.

Parece que eso no debería ser un problema.

+0

"El proceso de llamada debe tener el privilegio SE_SYSTEMTIME_NAME". Alguna idea sobre asignar ese privilegio? –

+3

@Tim Joseph: los administradores y varias otras cuentas tienen este privilegio. Puede utilizar Procexp desde Sysinternals para verificar qué privilegios se otorgan a cada proceso y si están habilitados actualmente. La política de seguridad local se puede cambiar para asignar el privilegio a otras cuentas. –

+0

Precaución: Deberíamos indicar el tiempo de Greenwich como un parámetro 'st'.El sistema establece según su zona horaria ('GMT'). –

6

Bueno, si ocurre lo peor, siempre hay

System.Diagnostics.Process.Start("CMD", "/C TIME 19:58"); // set time to 7:58PM 
+0

Lamentablemente, esto no parece funcionar en Windows 7. Recibo el error "El cliente no tiene un privilegio requerido". Mi usuario es un administrador y esto se ha verificado en 3 máquinas separadas. Si tiene un trabajo para esto agradecería (al igual que muchos otros a juzgar por mi investigación) –

+4

J .: Tendría que iniciar el proceso con permisos elevados –

4

Su aplicación necesita ser elevada para cambiar el tiempo (ya que cambiar el tiempo podría hacer que los registros de actividades no sean ciertos) pero no para cambiar el huso horario. Ponga un manifiesto en su aplicación con requireAdministrator y la aplicación se elevará. (Para probar esto antes de hacer el manifiesto, haga clic con el botón secundario en su administrador y Ejecutar como Administrador. Esto elevará la aplicación solo una vez. Elevar es algo diferente de ser iniciado por alguien que está en el grupo Administradores. eligiendo use sus poderes.)

Es probable que al usuario no le guste el aviso UAC, por lo que si el cambio de horario es raro, divídalo en un exe por separado, ponga un manifiesto en la aplicación principal con asInvoker y otro en el cambio de tiempo con requireAdministrator, y ejecuta el cambiador de tiempo desde la aplicación principal con ShellExecute. Lo ideal es tener un botón o elemento de menú para que esto suceda y poner un icono de escudo en él para que el aviso de UAC no sorprenda al usuario. Rechazo las indicaciones de UAC que no esperaba.

Cuestiones relacionadas