2013-12-10 72 views
0

您好,我正在嘗試更改windows xp上的時區,並且我正在關注此guide。我正在使用C++,似乎沒有設置適當的特權標誌。 下面是代碼:在Windows XP上更改時區xp

TIME_ZONE_INFORMATION tzInfo, tzInfoNew, tzInfoTest; 
DWORD dwRet; 

HANDLE hToken; 
TOKEN_PRIVILEGES tkp; 

OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken); 
LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME , &tkp.Privileges[0].Luid); 
tkp.PrivilegeCount = 1; 
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 

dwRet = GetTimeZoneInformation(&tzInfo); 
std::wcout << "STANDARD NAME: " << tzInfo.StandardName << std::endl; 

tzInfoNew.Bias = tzInfo.Bias + 60; 
StringCchCopy(tzInfoNew.StandardName, 32, L"Nikola Time Zone"); 
tzInfoNew.StandardDate.wMonth = 10; 
tzInfoNew.StandardDate.wDayOfWeek = 0; 
tzInfoNew.StandardDate.wDay = 5; 
tzInfoNew.StandardDate.wHour = 2; 

StringCchCopy(tzInfoNew.DaylightName, 32, L"Nikola Daylight Zone"); 
tzInfoNew.DaylightDate.wMonth = 4; 
tzInfoNew.DaylightDate.wDayOfWeek = 0; 
tzInfoNew.DaylightDate.wDay = 1; 
tzInfoNew.DaylightDate.wHour = 2; 
tzInfoNew.DaylightBias = -60; 


if(!SetTimeZoneInformation(&tzInfoNew)) 
{ 
    printf("STZI failed (%d)\n", GetLastError()); 
} 
dwRet = GetTimeZoneInformation(&tzInfoTest); 
std::wcout << "STANDARD NEW NAME: " << tzInfoTest.StandardName << std::endl; 
std::wcout << "STANDARD NEW DAYLIGHT NAME: " << tzInfoTest.DaylightName << std::endl; 

tkp.Privileges[0].Attributes = 0; 
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); 

編輯: 我已經插入這個方法在我的項目,我有一些奇怪的問題。反正我現在用的是以下結構:

typedef struct { 
    unsigned short month; 
    unsigned short week; 
    unsigned short day; 
} dstDate; 

typedef struct { 
    unsigned short hour; 
    unsigned short minute; 
    unsigned short second; 
} dstTime; 

這裏是整個方法一起:

bool::setTimeZone(short int timeZone, short int dstOffset, dstDate& sDate, dstTime& sTime, dstDate& eDate, dstTime& eTime){ 
    bool res = true; 

    TIME_ZONE_INFORMATION tzInfoNew; 

    HANDLE hToken; 
    TOKEN_PRIVILEGES tkp; 

    // Get the necessary priviledge to perform time zone setting operation 
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken); 
    LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME , &tkp.Privileges[0].Luid); 
    tkp.PrivilegeCount = 1; 
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 

    // Fill the TIME_ZONE_INFORMATION structure 
    ZeroMemory(&tzInfoNew, sizeof(tzInfoNew)); 
    tzInfoNew.Bias = (LONG) -timeZone; 

    // Start of DST 
    // If the following six lines are executed, then setting the time zone fails 
    // i.e. it goes with result status 0, but the time zone is not changed 
    tzInfoNew.DaylightDate.wMonth = sDate.month; 
    tzInfoNew.DaylightDate.wDayOfWeek = sDate.week; 
    tzInfoNew.DaylightDate.wDay = sDate.day; 
    tzInfoNew.DaylightDate.wHour = sTime.hour; 
    tzInfoNew.DaylightDate.wMinute = sTime.minute; 
    tzInfoNew.DaylightBias = dstOffset; 

    // End of DST 
    tzInfoNew.StandardDate.wMonth = eDate.month; 
    tzInfoNew.StandardDate.wDayOfWeek = eDate.week; 
    tzInfoNew.StandardDate.wDay = eDate.day; 
    tzInfoNew.StandardDate.wHour = eTime.hour; 
    tzInfoNew.StandardDate.wMinute = eTime.minute; 

    if(!SetTimeZoneInformation(&tzInfoNew)) { 
    printf("STZI failed (%d)\n", GetLastError()); 
    res = false; 
    } 

    tkp.Privileges[0].Attributes = 0; 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); 

    return (res); 
} 

所以SetTimeZoneInformation返回狀態OK,但時區未設置。只有在設置了DaylightDate信息時纔會出現問題,否則就沒關係。

+0

什麼是錯誤值? [documentation](http://msdn.microsoft.com/en-us/library/windows/desktop/ms724944%28v=vs.85%29.aspx)指出:「一個應用程序必須具有此函數的SE_TIME_ZONE_NAME特權才能成功。「還有一些示例代碼。 –

+0

SE_TIME_ZONE_NAME自Windows Vista開始實施,因此您無法將其用於XP。該文檔指出,對於XP SE_SYSTEMTIME_NAME需要使用。 沒有錯誤cuz函數返回0.但是,當我稍後檢索時區信息時,它表明時區未更改 – nikolakoco

+0

您是對的,我錯過了XP註釋,對此抱歉。 –

回答

1

在設置任何數據之前,我發現了問題,我沒有在TimeZoneInformation結構中使用ZeroMemory宏。

ZeroMemory(&tzInfoNew, sizeof(tzInfoNew)); 
tzInfoNew.Bias = 0; 
StringCchCopy(tzInfoNew.StandardName, 32, L"Test Time Zone"); 
..... 

我認爲這是無關緊要的使用它。但它做到了,我不太清楚爲什麼,因爲我已經設置了所有必要的信息,並且在設置時區時結構已滿。

+0

很高興你知道了。它看起來像'StandardBias',SYSTEMTIME'結構中的一些變量沒有被初始化,並且基於填充它的複雜規則,你幾乎保證了一個奇怪的衝突。 –

+0

是的你是對的,但它讓我困惑,沒有任何錯誤代碼 – nikolakoco

+0

現在有一個新問題,請參閱問題的編輯部分。 – nikolakoco