C# 22H2之后的windows版本使用SetDynamicTimeZoneInformation设置时区失败处理

使用SetDynamicTimeZoneInformation设置时区返回false,设置失败。

使用PowerShell设置Set-TimeZone成功。

/// <summary>
/// 设置本地时区
/// 参数取值"China Standard Time",即可设置为中国时区
/// </summary>
/// <param name="timeZoneId"></param>
/// <returns></returns>
public static bool SetLocalTimeZone(string timeZoneId)
{
    var dynamicTimeZoneInformation = ConvertDynamicTimeZoneInformation(timeZoneId);
    bool success;
    // 检测当前系统是否为旧系统
    if (IsOldOsVersion())
    {
        var tzi = ConvertTimeZoneInformation(dynamicTimeZoneInformation);
        success = SetTimeZoneInformation(ref tzi);
    }
    else
    {
        success = SetDynamicTimeZoneInformation(ref dynamicTimeZoneInformation);
    }
    if (success)
    {
        TimeZoneInfo.ClearCachedData(); // 清除缓存
    }
    else
    {
        success = SetTimeZoneByPowerShell(dynamicTimeZoneInformation.timeZoneKeyName);
    }
    return success;
}

/// <summary>
/// 根据时区名获取对应的DynamicTimeZoneInformation
/// </summary>
/// <param name="timeZoneName"></param>
/// <returns></returns>
private static DynamicTimeZoneInformation ConvertDynamicTimeZoneInformation(string timeZoneName)
{
    var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
    var info = new DynamicTimeZoneInformation
    {
        standardName = timeZoneInfo.StandardName,
        standardDate = new SystemTime(),
        daylightName = timeZoneInfo.DaylightName,
        daylightDate = new SystemTime(),
        timeZoneKeyName = timeZoneInfo.Id,
        dynamicDaylightTimeDisabled = false,
        bias = -Convert.ToInt32(timeZoneInfo.BaseUtcOffset.TotalMinutes)
    };
    return info;
}

/// <summary>
/// 判断Windows系统是否为旧版本
/// </summary>
/// <returns></returns>
public static bool IsOldOsVersion()
{
    var os = Environment.OSVersion;
    return os.Platform != PlatformID.Win32NT || os.Version.Major < 6;
}

/// <summary>
/// 将DynamicTimeZoneInformation转换为TimeZoneInformation
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
private static TimeZoneInformation ConvertTimeZoneInformation(DynamicTimeZoneInformation info)
{
    return new TimeZoneInformation
    {
        bias = info.bias,
        standardName = info.standardName,
        standardDate = info.standardDate,
        standardBias = info.standardBias,
        daylightName = info.daylightName,
        daylightDate = info.daylightDate,
        daylightBias = info.daylightBias
    };
}

// 针对于旧Windows系统,如Windows XP
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern int GetTimeZoneInformation(ref TimeZoneInformation lpTimeZoneInformation);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetTimeZoneInformation(ref TimeZoneInformation lpTimeZoneInformation);

//针对于新Windows系统,如Windows 7,Windows 8, Windows10
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern int GetDynamicTimeZoneInformation(ref DynamicTimeZoneInformation lpDynamicTimeZoneInformation);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetDynamicTimeZoneInformation(ref DynamicTimeZoneInformation lpDynamicTimeZoneInformation);

/// <summary>
/// 通过PowerShell设置时区
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static bool SetTimeZoneByPowerShell(string id)
{
    using var powerShell = PowerShell.Create();
    try
    {
        //通过PowerShell设置时区
        powerShell.AddCommand("Set-TimeZone").AddParameter("Id", id);
        powerShell.Invoke();
    }
    catch (Exception)
    {
        return false;
    }

    return true;
 }

 

posted @ 2023-11-19 11:36  log9527  阅读(18)  评论(0编辑  收藏  举报