上下文:目前在VisualStudio2012中开发/维护的程序,用VB(.NET)编写,针对Framework v3.5。我们的大多数客户都安装了荷兰语 Windows,并且他们中的大多数人将区域设置设置为荷兰语 (nl-NL),这意味着 . (句点) 用于分组, , (逗号) 作为小数分隔符。
在我们近 10,000 名客户中,只有一 (1) 名出现问题,我们确定其原因是调用 SHGetFileInfo 以获取文件的(小)图标。代码中的相关语句:
Private Declare Unicode Function SHGetFileInfo Lib "Shell32.dll" Alias "SHGetFileInfoW" (pszPath As String, dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, cbSizeFileInfo As UInteger, uFlags As UInteger) As IntPtr
和
Dim result As IntPtr = SHGetFileInfo(pszPath, dwFileAttributes, psfi, cbSizeFileInfo, uFlags)
我们评估 - 在该客户的特定 PC 上 - 在(第一次)调用 SHGetFileInfo 之前,System.Globalization.CultureInfo.CurrentCulture 是 (nl-NL),正如预期的那样,但在调用之后 CurrentCulture 立即切换到(en -US),这显然在其他地方引起了问题。
此时暂停代码并检查配置面板,区域设置仍然是荷兰语(nl-NL)。此外,代码中没有捕获到 SystemEvents.UserPreferenceChanged(或 -Changing)事件。停止并重新启动程序后,程序中的 CurrentCulture 再次为荷兰语 (nl-NL) - 直到第一次 SHGetFileInfo 调用。
实际上,我们通过在必要时重置 CurrentCulture 解决了这个问题:
Private Declare Unicode Function SHGetFileInfo0 Lib "Shell32.dll" Alias "SHGetFileInfoW" (pszPath As String, dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, cbSizeFileInfo As UInteger, uFlags As UInteger) As IntPtr
Private Shared Function SHGetFileInfo(pszPath As String, dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, cbSizeFileInfo As UInteger, uFlags As UInteger) As IntPtr
Dim ciBefore As System.Globalization.CultureInfo = Application.CurrentCulture
Dim result As IntPtr = SHGetFileInfo0(pszPath, dwFileAttributes, psfi, cbSizeFileInfo, uFlags)
Dim ciAfter As System.Globalization.CultureInfo = Application.CurrentCulture
If (ciAfter.Name <> ciAfter.Name) OrElse (ciBefore IsNot ciAfter) Then
Application.CurrentCulture = ciBefore
End If
Return result
End Function
由于问题只出现在特定的客户 PC 上,我不得不在他的 PC 上分析问题,从而限制了我检查问题的时间。所以,在实际意义上为他解决了这个问题之后,我留下了一个令人不快的事实,我不知道这怎么会发生,因此我的问题是:任何人都可以在这种黑暗中有所启发吗?
附加信息:客户直到一个月前才遇到此问题。最近,他开始使用(并且可能已安装)DropBox 和 BoxSync。我不知道这些的内部工作原理,但由于它们也“使用文件”并且它们的安装或多或少与出现的问题相吻合,我确实怀疑可能存在联系。
我希望我已经充分说明了这个问题,但如果需要更多信息,我很乐意尝试提供。任何帮助将不胜感激。在此先感谢您的任何建议。