【问题标题】:Localizing Windows Forms with .NET 3.5使用 .NET 3.5 本地化 Windows 窗体
【发布时间】:2013-05-08 10:53:41
【问题描述】:

我在使用目标 .NET 3.5 框架制作可本地化的 WinForms 应用程序时遇到问题。

我正在遵循 MSDN 的指南: http://msdn.microsoft.com/en-us/library/y99d1cd3%28v=vs.90%29.aspx

在我遵循演练并创建可本地化的表单并将Thread.CurrentThread.CurrentUICulture 设置为某种文化之后,它仅在我将“.NET Framework 4”设置为目标框架时才有效。在使用“.NET Framework 3.5”作为目标框架重新编译应用程序后,我无法显示与默认不同的语言,因此设置 CurrentUICulture 不会影响显示的文本。

我找不到有关此问题的任何信息,以及 .NET 3.5 和 .NET 4.0 中存在不同行为的任何信息。有没有人有类似的问题,或者知道我描述的行为原因是什么?

更多解释:

  1. 我在InitializeComponents方法之前设置CurrentUICulture

    public partial class Form1 : Form 
    {
        public Form1()
        {
            Thread.CurrentThread.CurrentUICulture = new CultureInfo("pl-PL");
            InitializeComponent();
        }
    }
    
  2. 在 .NET 4.0 中一切正常,但当我将其更改为 .NET 3.5 时却不是这样。

  3. 我正在使用 Visual C# 2010 Express。

【问题讨论】:

  • 你什么时候设置CurrentUICulture?它必须在资源加载之前(即在程序开始时显示任何表单之前)。它绝对适用于 .Net 3.5,我们将它用于所有 3.5 Windows 窗体程序。
  • 我将它设置在主窗体构造函数之前的 InitializeComponent 方法之前,如演练中所述。只是为了确保我也在 Program.Main 方法的开头也更改了它,但它也没有帮助

标签: c# .net winforms localization .net-3.5


【解决方案1】:

我知道我参加聚会已经很晚了,但由于我花了好几个小时才找到解决方案,所以我想与你分享。该解决方案适用于 Visual Studio 2017。

我猜这个问题与讨论的问题有关:https://developercommunity.visualstudio.com/content/problem/5735/when-vs-2017-rc-is-installed-resourcesdll-is-gener.html

问题在于 VS 2017 使用 .NET 4.0 编译资源附属程序集 dll,这导致它们被编译为 .NET 2.0 可执行文件的 exe 静默忽略。

解决方法是启动Visual Studio Installer,点击Visual Studio Community 2017下方的ModifyIndividual components 选项卡的更改并选择并安装 .NET Framework 3.5 开发工具

【讨论】:

  • 谢谢。在我使用 Visual Studio 安装程序安装了 .net Framework 3.5 开发工具后,一切正常! (VS 2019)
【解决方案2】:

如下设置文化

public MainForm()
{
    // Set default culture before initialisation.
    SetCurrentCulture();
    InitializeComponent();
}

SetCurrentCulture 如下所示并设置默认区域性。这需要在InitializeComponent 调用之前执行。

public static void SetCurrentCulture(CultureInfo cultureInfo)
{
    Thread.CurrentThread.CurrentCulture = cultureInfo;
    Thread.CurrentThread.CurrentUICulture = cultureInfo;
    CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
    CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
}

CultureInfo.DefaultThreadCurrentCultureCultureInfo.DefaultThreadCurrentUICulture 是在 .NET4.5+ 中引入的,用于告诉从主 UI 线程分离出来的任何后续线程,默认区域性应该是指定的值。这可能与您使用 .NET4.0 无关。

我希望这会有所帮助。

【讨论】:

  • 感谢您的回答,但在我的情况下它无济于事。我将文化设置在正确的位置,它适用于 .NET 4.0,但在我将目标框架更改为 .NET 3.5 后立即停止。我编辑了我的帖子以提供更多见解。
【解决方案3】:

我想把这个话题带回来,因为我有同样的问题,bozydar.sz(卸载 .NET 4.5)的解决方案对我来说似乎不可接受。在将我的 Windows Forms 应用程序定位到 .NET 3.5 框架时,我发现 Visual Studio 2012(Express,Desktop)存在同样的问题。我使用ildasm 检查了资源 DLL,发现资源 DLL 是使用 4.0 运行时构建的,即使目标框架是 3.5。

MicrosoftDev Center 报告了使用 VS2012 Express 的相同问题,但未报告解决方案。在 Stackoverflow 上的 another post 中,也报告了 VS2012 和目标框架

我为“构建操作”和 *.resx 文件的其他属性尝试了不同的设置,但没有成功。

接下来,我验证了这个问题如下:我安装了Windows SDK for Windows 7 and .NET 3.5 SP1。在该 Windows SDK 7.0 的命令提示符下,我使用 msbuild 3.5 构建了 Visual Studio 2012 sln 文件。这次用ildasm 检查资源DLL 给了我2.0.50727 版本,这是我在这里所期望的。当我用我在部署中从 msbuild 3.5 获得的资源 DLL 替换原始部署的资源 DLL(来自具有目标框架 3.5 和 ToolsVersion 4.0 的 VS2012 发布对话框)时,问题得到了解决:Windows 窗体应用程序的本地化是正确的现在。但是,使用 msbuild 3.5 仍然不是一个长期的解决方案。如果 VS2012 中提供了目标框架 3.5,我希望它能够正常运行。

在 Visual Studio 2013 RC 中观察到相同的行为:资源 DLL 的版本为 4.0 而不是 2.0。主应用程序无法加载资源 DLL。

This answer 用户 Dan Malcom 在 Stackoverflow 上的另一个问题让我找到了一个对我有用的注册表黑客:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0]
"MSBuildToolsPath"="c:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\"
"MSBuildToolsRoot"="c:\\Windows\\Microsoft.NET\\Framework64\\"
"FrameworkSDKRoot"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0A@InstallationFolder)"
"MSBuildRuntimeVersion"="4.0.30319"
"SDK40ToolsPath"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0A\\WinSDK-NetFx40Tools-x86@InstallationFolder)"
"SDK35ToolsPath"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.0\\WinSDKNetFx35Tools@InstallationFolder)"
"MSBuildToolsPath32"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\MSBuild\\ToolsVersions\\4.0@MSBuildToolsPath)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0\11.0]
"FrameworkSDKRoot"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0A@InstallationFolder)"
 "SDK40ToolsPath"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0A\\WinSDK-NetFx40Tools-x86@InstallationFolder)"
"SDK35ToolsPath"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.0\\WinSDKNetFx35Tools@InstallationFolder)"
"WindowsSDK80Path"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0@InstallationFolder)"

我的注册表中的原始键是:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0]
"MSBuildToolsPath"="c:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\"
"MSBuildToolsRoot"="c:\\Windows\\Microsoft.NET\\Framework64\\"
"FrameworkSDKRoot"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.0A@InstallationFolder)"
"MSBuildRuntimeVersion"="4.0.30319"
"SDK40ToolsPath"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.0A\\WinSDK-NetFx40Tools-x86@InstallationFolder)"
"SDK35ToolsPath"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.0A\\WinSDK-NetFx35Tools-x86@InstallationFolder)"
"MSBuildToolsPath32"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\MSBuild\\ToolsVersions\\4.0@MSBuildToolsPath)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0\11.0]
"FrameworkSDKRoot"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0A@InstallationFolder)"
"SDK40ToolsPath"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0A\\WinSDK-NetFx40Tools-x86@InstallationFolder)"
"SDK35ToolsPath"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0A\\WinSDK-NetFx35Tools-x86@InstallationFolder)"
"WindowsSDK80Path"="$(Registry:HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0@InstallationFolder)"

我导出了注册表项,对其进行了编辑,最后运行了文件以更正这些项。对于注册表的Wow6432Node,我也是这样做的。

我原来的注册表存在以下问题(一定是我安装VS2012和Windows SDK 7.0后的状态):

  • ToolsVersions\4.0 键中的FrameworkSDKRoot 值引用了 Windows SDK 7.0A(VS2010 附带的)中的一个键,但我的机器上从未安装过这个版本。
  • SDK40ToolsPathSDK35ToolsPath 值也是如此。
  • ToolsVersions\4.0\11.0 键中的 SDK35ToolsPath 值引用了一个不存在的 WinSDK-NetFx35Tools-x86
  • Wow6432Node 中,所有FrameworkSDKRootSDK35ToolsPathSDK40ToolsPath 都不正确(引用不存在的注册表值)。

编辑注册表可以解决问题,但代价高昂:需要将此更改应用于每台开发计算机/构建服务器。

【讨论】:

    【解决方案4】:

    我发现问题是由我安装的 Visual C# Express 或 .NET 4.5 引起的(不确定哪一个是问题的根源)。

    在我使用 ILSpy 检查我的资源附属 DLL 后,似乎即使我使用 .NET 3.5 构建我的项目,资源 DLL 也是使用 4.0 运行时构建的,并且无法由应用程序加载。这就是为什么文本没有改变的原因,即使我改变了CurrentUICulture

    卸载 .NET 4.5 并重新安装 Visual C# 2010 Express 解决了该问题。现在,带有资源的卫星 DLL 是使用 2.0 运行时构建的,并且可以由我的应用程序正确加载。

    【讨论】:

      猜你喜欢
      • 2010-10-15
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多