SetDynamicTimeZoneInformation
,否则“
无法识别您当前的时区。请使用下面的链接选择有效的时区。
“将显示,直到下次重新启动。
好处:调用SetDynamicTimeZoneInformation不需要手动编辑注册表,因此不需要以管理员身份启动程序。
下面是Cloudlessky的代码片段,修改后可用于Vista和更高版本
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace TimeZoneTest
{
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct SystemTime
{
[MarshalAs(UnmanagedType.U2)]
public short Year;
[MarshalAs(UnmanagedType.U2)]
public short Month;
[MarshalAs(UnmanagedType.U2)]
public short DayOfWeek;
[MarshalAs(UnmanagedType.U2)]
public short Day;
[MarshalAs(UnmanagedType.U2)]
public short Hour;
[MarshalAs(UnmanagedType.U2)]
public short Minute;
[MarshalAs(UnmanagedType.U2)]
public short Second;
[MarshalAs(UnmanagedType.U2)]
public short Milliseconds;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TimeZoneInformation
{
[MarshalAs(UnmanagedType.I4)]
public int Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string StandardName;
public SystemTime StandardDate;
[MarshalAs(UnmanagedType.I4)]
public int StandardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string DaylightName;
public SystemTime DaylightDate;
[MarshalAs(UnmanagedType.I4)]
public int DaylightBias;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DynamicTimeZoneInformation
{
public int Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string StandardName;
public SystemTime StandardDate;
public int StandardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DaylightName;
public SystemTime DaylightDate;
public int DaylightBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string TimeZoneKeyName;
[MarshalAs(UnmanagedType.U1)]
public bool DynamicDaylightTimeDisabled;
}
[StructLayout(LayoutKind.Sequential)]
public struct RegistryTimeZoneInformation
{
[MarshalAs(UnmanagedType.I4)]
public int Bias;
[MarshalAs(UnmanagedType.I4)]
public int StandardBias;
[MarshalAs(UnmanagedType.I4)]
public int DaylightBias;
public SystemTime StandardDate;
public SystemTime DaylightDate;
public RegistryTimeZoneInformation(TimeZoneInformation tzi)
{
this.Bias = tzi.Bias;
this.StandardDate = tzi.StandardDate;
this.StandardBias = tzi.StandardBias;
this.DaylightDate = tzi.DaylightDate;
this.DaylightBias = tzi.DaylightBias;
}
public RegistryTimeZoneInformation(byte[] bytes)
{
if ((bytes == null) || (bytes.Length != 0x2c))
{
throw new ArgumentException("Argument_InvalidREG_TZI_FORMAT");
}
this.Bias = BitConverter.ToInt32(bytes, 0);
this.StandardBias = BitConverter.ToInt32(bytes, 4);
this.DaylightBias = BitConverter.ToInt32(bytes, 8);
this.StandardDate.Year = BitConverter.ToInt16(bytes, 12);
this.StandardDate.Month = BitConverter.ToInt16(bytes, 14);
this.StandardDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x10);
this.StandardDate.Day = BitConverter.ToInt16(bytes, 0x12);
this.StandardDate.Hour = BitConverter.ToInt16(bytes, 20);
this.StandardDate.Minute = BitConverter.ToInt16(bytes, 0x16);
this.StandardDate.Second = BitConverter.ToInt16(bytes, 0x18);
this.StandardDate.Milliseconds = BitConverter.ToInt16(bytes, 0x1a);
this.DaylightDate.Year = BitConverter.ToInt16(bytes, 0x1c);
this.DaylightDate.Month = BitConverter.ToInt16(bytes, 30);
this.DaylightDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x20);
this.DaylightDate.Day = BitConverter.ToInt16(bytes, 0x22);
this.DaylightDate.Hour = BitConverter.ToInt16(bytes, 0x24);
this.DaylightDate.Minute = BitConverter.ToInt16(bytes, 0x26);
this.DaylightDate.Second = BitConverter.ToInt16(bytes, 40);
this.DaylightDate.Milliseconds = BitConverter.ToInt16(bytes, 0x2a);
}
}
public class TokenPrivilegesAccess
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int OpenProcessToken(int ProcessHandle, int DesiredAccess,
ref int tokenhandle);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetCurrentProcess();
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int LookupPrivilegeValue(string lpsystemname, string lpname,
[MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int AdjustTokenPrivileges(int tokenhandle, int disableprivs,
[MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGE Newstate, int bufferlength,
int PreivousState, int Returnlength);
public const int TOKEN_ASSIGN_PRIMARY = 0x00000001;
public const int TOKEN_DUPLICATE = 0x00000002;
public const int TOKEN_IMPERSONATE = 0x00000004;
public const int TOKEN_QUERY = 0x00000008;
public const int TOKEN_QUERY_SOURCE = 0x00000010;
public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public const int TOKEN_ADJUST_GROUPS = 0x00000040;
public const int TOKEN_ADJUST_DEFAULT = 0x00000080;
public const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001;
public const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
public const UInt32 SE_PRIVILEGE_REMOVED = 0x00000004;
public const UInt32 SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000;
public static bool EnablePrivilege(string privilege)
{
try
{
int token = 0;
int retVal = 0;
TOKEN_PRIVILEGE TP = new TOKEN_PRIVILEGE();
LUID LD = new LUID();
retVal = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token);
retVal = LookupPrivilegeValue(null, privilege, ref LD);
TP.PrivilegeCount = 1;
var luidAndAtt = new LUID_AND_ATTRIBUTES();
luidAndAtt.Attributes = SE_PRIVILEGE_ENABLED;
luidAndAtt.Luid = LD;
TP.Privilege = luidAndAtt;
retVal = AdjustTokenPrivileges(token, 0, ref TP, 1024, 0, 0);
return true;
}
catch
{
return false;
}
}
public static bool DisablePrivilege(string privilege)
{
try
{
int token = 0;
int retVal = 0;
TOKEN_PRIVILEGE TP = new TOKEN_PRIVILEGE();
LUID LD = new LUID();
retVal = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token);
retVal = LookupPrivilegeValue(null, privilege, ref LD);
TP.PrivilegeCount = 1;
// TP.Attributes should be none (not set) to disable privilege
var luidAndAtt = new LUID_AND_ATTRIBUTES();
luidAndAtt.Luid = LD;
TP.Privilege = luidAndAtt;
retVal = AdjustTokenPrivileges(token, 0, ref TP, 1024, 0, 0);
return true;
}
catch
{
return false;
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LUID
{
internal uint LowPart;
internal uint HighPart;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LUID_AND_ATTRIBUTES
{
internal LUID Luid;
internal uint Attributes;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TOKEN_PRIVILEGE
{
internal uint PrivilegeCount;
internal LUID_AND_ATTRIBUTES Privilege;
}
public class Program
{
public const int ERROR_ACCESS_DENIED = 0x005;
public const int CORSEC_E_MISSING_STRONGNAME = -2146233317;
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetTimeZoneInformation([In] ref TimeZoneInformation lpTimeZoneInformation);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetDynamicTimeZoneInformation([In] ref DynamicTimeZoneInformation lpTimeZoneInformation);
public static void Main(string[] args)
{
var regTimeZones = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones");
// Print out all the possible time-zones.
//foreach(var subKey in regTimeZones.GetSubKeyNames())
//{
// Console.WriteLine(subKey);
//}
var subKey = regTimeZones.GetSubKeyNames().Where(s => s == "Atlantic Standard Time").First();
string daylightName = (string)regTimeZones.OpenSubKey(subKey).GetValue("Dlt");
string standardName = (string)regTimeZones.OpenSubKey(subKey).GetValue("Std");
byte[] tzi = (byte[])regTimeZones.OpenSubKey(subKey).GetValue("TZI");
var regTzi = new RegistryTimeZoneInformation(tzi);
TokenPrivilegesAccess.EnablePrivilege("SeTimeZonePrivilege");
bool didSet;
if (Environment.OSVersion.Version.Major < 6)
{
var tz = new TimeZoneInformation();
tz.Bias = regTzi.Bias;
tz.DaylightBias = regTzi.DaylightBias;
tz.StandardBias = regTzi.StandardBias;
tz.DaylightDate = regTzi.DaylightDate;
tz.StandardDate = regTzi.StandardDate;
tz.DaylightName = daylightName;
tz.StandardName = standardName;
didSet = Program.SetTimeZoneInformation(ref tz);
}
else
{
var tz = new DynamicTimeZoneInformation();
tz.Bias = regTzi.Bias;
tz.DaylightBias = regTzi.DaylightBias;
tz.StandardBias = regTzi.StandardBias;
tz.DaylightDate = regTzi.DaylightDate;
tz.StandardDate = regTzi.StandardDate;
tz.DaylightName = daylightName;
tz.StandardName = standardName;
tz.TimeZoneKeyName = subKey;
tz.DynamicDaylightTimeDisabled = false;
didSet = Program.SetDynamicTimeZoneInformation(ref tz);
}
int lastError = Marshal.GetLastWin32Error();
TokenPrivilegesAccess.DisablePrivilege("SeTimeZonePrivilege");
if (didSet)
{
Console.WriteLine("Success, TimeZone Set!");
}
else
{
if (lastError == Program.ERROR_ACCESS_DENIED)
{
Console.WriteLine("Error: Access denied... Try running application as administrator.");
}
else if (lastError == Program.CORSEC_E_MISSING_STRONGNAME)
{
Console.WriteLine("Error: Application is not signed ... Right click the project > Signing > Check 'Sign the assembly'.");
}
else
{
Console.WriteLine("Win32Error: " + lastError + "\nHRESULT: " + Marshal.GetHRForLastWin32Error());
}
}
Console.ReadLine();
}
}
}