2013-07-08 30 views
1

我的程序需要能夠更改機器上的SystemDate。環顧四周後,我發現這個代碼並實現了它,但它似乎並沒有改變日期。它正在運行的虛擬機已關閉時間同步,所以我知道問題不在於此。我犯了一個小錯誤,還是有更簡單的方法來更改系統日期?如何在c中更改系統日期#

[StructLayout(LayoutKind.Sequential)] 
private 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; 
} 

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



public bool SetSystemDateTime(DateTime newDateTime) 
{ 
    bool result = false; 

    try 
    { 
     newDateTime = newDateTime.ToUniversalTime(); 

     SYSTEMTIME sysTime = new SYSTEMTIME() 
      { wYear = (short)newDateTime.Year /* must be short */, 
      wMonth = (short)newDateTime.Month, 
      wDayOfWeek = (short)newDateTime.DayOfWeek, 
      wDay = (short)newDateTime.Day, 
      wHour = (short)newDateTime.Hour, 
      wMinute = (short)newDateTime.Minute, 
      wSecond = (short)newDateTime.Second, 
      wMilliseconds = (short)newDateTime.Millisecond }; 

     result = SetSystemTime(ref sysTime); 
    } 
    catch (Exception) 
    { 
     result = false; 
    } 
    return result; 
} 
+0

如果拋出異常,它說什麼? –

+0

您是否以管理員身份運行Visual Studio? – keyboardP

+0

@RubensMariuzzo我不太確定,它還沒有拋出異常。 – JBelter

回答

2

以管理員身份運行它,因爲它適用於我。代碼來自SetSystemTime的文檔,雖然我在設置時間後添加了額外的Console.Read,以便在系統時間恢復到原始時間之前可以看到系統時間已更改。

public struct SYSTEMTIME 
{ 
    public ushort wYear, wMonth, wDayOfWeek, wDay, 
      wHour, wMinute, wSecond, wMilliseconds; 
} 

[DllImport("kernel32.dll")] 
public extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime); 

[DllImport("kernel32.dll")] 
public extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime); 

Console.WriteLine(DateTime.Now.ToString()); 
SYSTEMTIME st = new SYSTEMTIME(); 
GetSystemTime(ref st); 

Console.WriteLine("Adding 1 hour..."); 
st.wHour = (ushort)(st.wHour + 1 % 24); 
if (SetSystemTime(ref st) == 0) 
    Console.WriteLine("FAILURE: SetSystemTime failed"); 

Console.WriteLine(DateTime.Now.ToString()); 
Console.Read(); 

Console.WriteLine("Setting time back..."); 
st.wHour = (ushort)(st.wHour - 1 % 24); 
SetSystemTime(ref st); 
Console.WriteLine(DateTime.Now.ToString()); 
Console.WriteLine("Press Enter to exit"); 
Console.Read(); 
+0

此代碼有效,所以我會重構我的行爲更像這個。謝謝。 – JBelter

1

的應用正在以管理員身份運行

這沒有太大意義,這些天,很多用戶登錄到Windows的管理員帳戶。重要的是你運行這個代碼提升。這需要a manifest與「requireAdministrator」屬性,以便用戶獲得UAC提升提示。

代碼中的重大缺陷是它很容易忽略函數的返回值。也沒有辦法找出它爲什麼返回false。 [DllImport]有缺陷,它不會將SetLastError屬性設置爲true。捕捉異常而不生成診斷是一個非常糟糕的主意,請刪除它。修復:

[DllImport("kernel32.dll", SetLastError = true)] 
private static extern bool SetSystemTime(ref SYSTEMTIME lpSystemTime); 
... 
if (!SetSystemTime(ref sysTime)) { 
    throw new System.ComponentModel.Win32Exception(); 
} 
+0

如果我在清單中添加,是否會在我的虛擬機(運行Windows Server 2003 R2)上運行應用程序,因爲Windows Server 2003上沒有UAC,會不會搞砸了? – JBelter

+1

不,它會忽略它不理解的清單中的條目。 –

相關問題