2009-03-16 28 views

Respuesta

60

Here is where I found the answer.

he vuelto a publicar aquí para mejorar la claridad.

Definir esta estructura:

[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; 
} 

Añadir la extern método siguiente a la clase:

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

luego llamar al método con una instancia de su estructura como esta:

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. 
+4

escribiendo un envoltorio personalizado de C++/CLI e introduciendo otro ensamblaje es más fácil que escribir una estructura de ~ 9 líneas? – Lucas

+4

El espacio de nombres Microsoft.VisualStudio.Shell.Interop contiene una definición de la estructura SYSTEMTIME; vea http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.systemtime.aspx –

+0

¡No deje que Marc Gravell vea su estructura! ;-) – si618

7
  1. PInvoke para llamar a la API de Win32 SetSystemTime, (example)
  2. clases System.Management con clase WMI Win32_OperatingSystem y llamar SetDateTime en dicha clase.

Ambos requieren que a la persona que llama se le haya concedido SeSystemTimePrivilege y que este privilegio esté habilitado.

14

Puede usar una llamada a un comando DOS pero invocar la función en la ventana dll es una mejor manera de hacerlo.

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); 
} 
4

Desde lo he mencionado en un comentario, aquí es un envoltorio de C++/CLI: código de cliente

#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); 
     } 
    }; 
} 

El C# es ahora muy simple:

JDanielSmith.Utilities.SetSystemTime(DateTime.Now); 
+0

Probé tu código, pero parece que no funciona. https://gist.github.com/jtara1/07cfd5ebffab8296564f86000c50510e De todos modos, encontré una solución a lo que quería y lo probé https://github.com/jtara1/MiscScripts/blob/00a5d330d784d7e423c0f8a83172ddfc31aad3fa/MiscScripts/UpdateOSTime.cs –

8

Una gran cantidad de grandes puntos de vista y los enfoques ya están aquí, pero aquí hay algunas especificaciones que están omitidas actualmente y que creo que podrían tropezar y confundir a algunas personas.

  1. En Windows Vista, 7, 8 OS esto va a requerir un mensaje de UAC con el fin de obtener los derechos administrativos necesarios para ejecutar con éxito la función SetSystemTime. El motivo es que el proceso de llamada necesita el privilegio SE_SYSTEMTIME_NAME.
  2. La función SetSystemTime está esperando una estructura SYSTEMTIME en tiempo universal coordinado (UTC). No funcionará como se desea de lo contrario.

Dependiendo de dónde/cómo se está recibiendo sus DateTime valores, tal vez sea mejor ir a lo seguro y el uso ToUniversalTime() antes de ajustar los valores correspondientes en el SYSTEMTIME estructura.

código de ejemplo:

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); 
+0

I no puedo cambiar directamente el tiempo del sistema usando este –

+0

He utilizado este código en múltiples proyectos con éxito. ¿Estás ejecutando el ejecutable como administrador? De lo contrario, este código no funcionará. –

+1

wow esto resolvió mi problema. El problema es que la zona horaria de su hora local se interpone en el camino para obtener la hora correcta para que la línea "DateTime dateTime = tempDateTime.ToUniversalTime();" lo resolvió todo. –

5

Utilice esta función para cambiar la hora de sistema (probado en la ventana 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(); 
     } 
    } 

Ejemplo: Call en el método de carga de la forma setDate ("5-6-92"); setTime ("2: 4: 5 AM");

+0

Aquí hay una versión probada, lista para compilar y ejecutar de su código https://github.com/jtara1/MiscScripts/blob/master/MiscScripts/UpdateOSTime.cs Tuve que pasar por al menos 4 stackoverflows para esto ya que estoy no está familiarizado con C# o estas libs. –

-2

proc.Arguments = "/ C Date:" + dateInYourSystemFormat;

Esta es una función de trabajo: "¿qué has"

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(); 
    } 
} 
+0

misma respuesta que le dieron ... –

Cuestiones relacionadas