.NET C# DateTimeFormat.LongTimePattern 不响应区域设置更改问题
问题场景
两台Windows Server 2016服务器上运行基于.NET Framework 4.7.2的Windows Service程序,执行以下代码创建en-US区域文化对象:
var cinfo = CultureInfo.CreateSpecificCulture("en-US");
读取cinfo.DateTimeFormat.LongTimePattern属性时两台机器返回结果不一致:
- 机器1:属性值与控制面板区域对话框中配置的Long Time格式完全一致
- 机器2:属性值不受控制面板区域对话框中Long Time格式设置影响,始终固定为
"h:mm:ss tt"
已确认两台机器的cinfo.UseUserOverride属性均为true,修改区域设置时面板选中的文化均为English (United States)。
差异原因
该行为差异由Windows服务的Session 0隔离机制,以及区域配置的生效范围共同导致:
- 普通用户在控制面板中修改的区域格式配置,默认仅对当前交互式登录的用户生效,配置存储在当前用户对应的
HKEY_CURRENT_USER\Control Panel\International注册表路径下。 - Windows服务默认运行在Session 0隔离环境中,使用Local System、Local Service、Network Service等内置系统账户执行,不会加载当前交互式登录用户的用户级注册表配置,只会读取自身运行账户对应的用户配置,或系统级默认区域配置。
- 机器1可以读取到控制面板修改的自定义格式,是因为之前执行过区域配置复制操作:在控制面板区域设置的「管理」页签中点击「复制设置」,将当前交互式用户的自定义配置同步到了「欢迎屏幕和系统账户」,服务运行的系统账户可以加载到这份自定义配置。
- 机器2未执行过上述配置同步操作,服务运行时读取的是en-US文化的系统内置默认时间格式
h:mm:ss tt,交互式用户在控制面板修改的配置不会同步到服务运行的账户上下文,因此无论怎么修改控制面板设置,服务读取到的值都不会变化。
验证方式:在服务代码中输出WindowsIdentity.GetCurrent().Name确认服务运行账户,再在注册表中定位到该账户SID对应的国际配置项,查看LongTime值即可和代码读取结果完全匹配。
内容的提问来源于stack exchange,提问作者Hugh Robinson
相关产品推荐
相关产品推荐

