Come posso modificare la data del sistema locale & in modo programmatico con C#?Modifica la data di sistema a livello di programmazione
risposta
Here is where I found the answer.
ho ripubblicato qui per migliorare la chiarezza.
Definire questa struttura:
[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;
}
Aggiungere il extern
seguente metodo alla classe:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetSystemTime(ref SYSTEMTIME st);
quindi chiamare il metodo con un'istanza della struct come questo:
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.
scrivere un wrapper C++/CLI personalizzato e intromettersi in un altro assembly è più facile che scrivere una struct ~ 9-line ?? – Lucas
Lo spazio dei nomi Microsoft.VisualStudio.Shell.Interop contiene una definizione della struttura SYSTEMTIME; vedi http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.systemtime.aspx –
Non lasciare che Marc Gravell veda la tua struttura! ;-) – si618
- PInvoke per chiamare API Win32 SetSystemTime, (example)
- classi System.Management con classe WMI Win32_OperatingSystem e chiamare SetDateTime quella classe.
Entrambi richiedono che al chiamante sia stato assegnato SeSystemTimePrivilege e che questo privilegio sia abilitato.
È possibile utilizzare una chiamata a un comando DOS ma il richiamo della funzione nelle finestre dll è un modo migliore per farlo.
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);
}
Dal momento che ho parlato in un commento, ecco 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);
}
};
}
Il C# codice del client è ora molto semplice:
JDanielSmith.Utilities.SetSystemTime(DateTime.Now);
Ho provato il tuo codice, ma non sembra funzionare. https://gist.github.com/jtara1/07cfd5ebffab8296564f86000c50510e Ad ogni modo, ho trovato una soluzione a ciò che volevo e l'ho testato https://github.com/jtara1/MiscScripts/blob/00a5d330d784d7e423c0f8a83172ddfc31aad3fa/MiscScripts/UpdateOSTime.cs –
Un sacco di grandi punti di vista e gli approcci sono già qui, ma qui ci sono alcune specifiche che sono attualmente tralasciate e che ritengo possano far scattare e confondere alcune persone.
- Su Windows Vista, 7, 8 OS questo sarà richiederà un prompt UAC per ottenere i diritti amministrativi necessari per eseguire con successo la funzione
SetSystemTime
. Il motivo è che il processo di chiamata richiede il privilegio SE_SYSTEMTIME_NAME. - La funzione
SetSystemTime
prevede una strutturaSYSTEMTIME
in tempo universale coordinato (UTC). Non funzionerà come desiderato altrimenti.
A seconda di dove/come hai trovato i tuoi DateTime
valori, potrebbe essere meglio andare sul sicuro e usare ToUniversalTime()
prima di impostare i valori corrispondenti nel SYSTEMTIME
struct.
Codice esempio:
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);
I Non posso cambiare direttamente il tempo di sistema usando questo –
Ho usato questo codice su più progetti con successo. Stai eseguendo l'eseguibile come amministratore? Altrimenti questo codice non funzionerà sicuramente. –
wow questo ha risolto il mio problema. Il problema è che il fuso orario per l'ora locale sta intralciando l'ora corretta in modo che la riga "DateTime dateTime = tempDateTime.ToUniversalTime();" risolto tutto –
Utilizzare questa funzione per modificare il tempo di sistema (testato in finestra 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();
}
}
Esempio: chiamata in modo carico di forma setDate ("5-6-92"); setTime ("2: 4: 5 AM");
Ecco una versione testata, pronta per la compilazione ed esecuzione del codice https://github.com/jtara1/MiscScripts/blob/master/MiscScripts/UpdateOSTime.cs Ho dovuto passare attraverso almeno 4 stackoverflow per questo come sono non ha familiarità con C# o queste librerie. –
proc.Arguments = "/ C Data:" + dateInYourSystemFormat;
Questa è la funzione lavoro: "che cosa hai provato"
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();
}
}
stessa risposta che hai dato ... –
divertente come alcune domande come queste solo ottenere una risposta, mentre altri sono di spam con ... strano ... –