我有一个delphi程序,可以将窗口的时区信息设置为特定的开始和结束日期。它可以在windows7、vista和Server2008中完美运行。但在诸如XP和Server 2003的早期windows版本中没有。我很好奇我的代码中是否有错误,或者这是XP的问题?
这是我的代码:
program SetTimeZoneInfo;
{$APPTYPE CONSOLE}
uses
SysUtils,
Messages,
windows;
const
SE_TIME_ZONE_NAME = 'SeTimeZonePrivilege';
SE_SYSTEMTIME_NAME = 'SeSystemtimePrivilege';
function NTSetPrivilege(sPrivilege: string; bEnabled: Boolean): Boolean;
var
hToken: THandle;
TokenPriv: TOKEN_PRIVILEGES;
PrevTokenPriv: TOKEN_PRIVILEGES;
ReturnLength: Cardinal;
begin
Result := True;
if not (Win32Platform = VER_PLATFORM_WIN32_NT) then Exit;
// obtain the processes token
if OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
try
// Get the locally unique identifier (LUID) .
if LookupPrivilegeValue(nil, PChar(sPrivilege),
TokenPriv.Privileges[0].Luid) then
begin
TokenPriv.PrivilegeCount := 1; // one privilege to set
case bEnabled of
True: TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
False: TokenPriv.Privileges[0].Attributes := 0;
end;
ReturnLength := 0; // replaces a var parameter
PrevTokenPriv := TokenPriv;
// enable or disable the privilege
AdjustTokenPrivileges(hToken, False, TokenPriv, SizeOf(PrevTokenPriv),
PrevTokenPriv, ReturnLength);
end;
finally
CloseHandle(hToken);
end;
end;
// test the return value of AdjustTokenPrivileges.
Result := GetLastError = ERROR_SUCCESS;
if not Result then
raise Exception.Create(SysErrorMessage(GetLastError));
end;
var
tzi: TTimeZoneInformation;
lpwdResult, LHResult: Cardinal;
begin
if Win32MajorVersion >= 6 then
begin
Writeln('NTSetPrivilege SE_TIME_ZONE_NAME enabled ? ' + BoolToStr(NTSetPrivilege(SE_TIME_ZONE_NAME, True), True));
end;
Writeln('NTSetPrivilege SE_TIME_ZONE_NAME enabled ? ' + BoolToStr(NTSetPrivilege(SE_SYSTEMTIME_NAME, True), True));
tzi.Bias:= -210;
tzi.DaylightDate.wYear:= 2012;
tzi.DaylightDate.wMonth:= 3;
tzi.DaylightDate.wDay:= 20;
tzi.DaylightDate.wHour:= 23;
tzi.DaylightDate.wMinute:= 59;
tzi.DaylightDate.wSecond:= 59;
tzi.DaylightBias:= -60;
tzi.StandardDate.wYear:= 2012;
tzi.StandardDate.wMonth:= 9;
tzi.StandardDate.wDay:= 20;
tzi.DaylightDate.wHour:= 23;
tzi.DaylightDate.wMinute:= 59;
tzi.DaylightDate.wSecond:= 59;
tzi.StandardBias:= 0;
if not SetTimeZoneInformation(tzi) then
Writeln('SetTimeZoneInformation Error Message: '+ SysErrorMessage(GetLastError))
else
Writeln('SetTimeZoneInformation : Success');
LHResult:= SendMessageTimeout(
HWND_BROADCAST, // reciever window handle
WM_SETTINGCHANGE, // message
0, // WParam
0, // LParam
SMTO_NORMAL, // return if reciever hange
5, // timeout in seconds
lpwdResult // result
);
if LHResult = 0 then
Writeln('SendMessageTimeout Error Message: '+ SysErrorMessage(GetLastError))
else
Writeln('SendMessageTimeout : Success');
if Win32MajorVersion >= 6 then
Writeln('NTSetPrivilege SE_TIME_ZONE_NAME disabled ? ' + BoolToStr(NTSetPrivilege(SE_TIME_ZONE_NAME, False), True));
Writeln('NTSetPrivilege SE_TIME_ZONE_NAME disabled ? ' + BoolToStr(NTSetPrivilege(SE_SYSTEMTIME_NAME, False), True));
Readln;
end.
当Windows是新版本时,请使用:SetDynamicTimeZoneInformation。当它是旧的(例如:XP)时,使用SetTimeZoneInformation。告诉我它是否解决了问题。我也必须做一些类似的事情。谢谢Rodrigo Pimenta Carvalho