0

我有一个德尔福程序,将窗口的时区信息设置为特定的开始和结束日期。它在 Windows 7、vista 和 Server 2008 中完美运行。但在 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.
4

1 回答 1

0

Windows 为新版本时,使用:SetDynamicTimeZoneInformation。如果它是旧的(例如:XP),请像以前一样使用 SetTimeZoneInformation。告诉我它是否解决了问题。我也必须做类似的事情。谢谢。罗德里戈·皮门塔·卡瓦略

于 2013-09-14T18:11:40.957 回答