相关疑难解决方法(0)

单组装多语言Windows Forms部署(ILMerge和附属程序集/本地化) - 可能吗?

我有一个简单的Windows窗体(C#,. NET 2.0)应用程序,使用Visual Studio 2008构建.

我想支持多种UI语言,并使用表单的"Localizable"属性和特定于文化的.resx文件,本地化方面可以无缝轻松地工作.Visual Studio会自动将特定于文化的resx文件编译为附属程序集,因此在我编译的应用程序文件夹中,存在包含这些附属程序集的特定于文化的子文件夹.

我希望将应用程序部署(复制到位)作为单个程序集,但仍保留包含多组特定于文化的资源的能力.

使用ILMerge(或ILRepack),我可以将附属程序集合并到主可执行程序集中,但标准的.NET ResourceManager回退机制找不到编译到主程序集中的特定于文化的资源.

有趣的是,如果我采用我的合并(可执行)程序集并将其副本放入特定于文化的子文件夹中,那么一切正常!同样,当我使用Reflector(或ILSpy)时,我可以在合并的组合中看到主要和特定于文化的资源.但是将主程序集复制到特定于文化的子文件夹中无论如何都会破坏合并的目的 - 我真的需要只有一个单一程序集的副本......

我想知道是否有任何方法可以劫持或影响ResourceManager回退机制,以在同一个程序集中查找特定于文化的资源,而不是在GAC和文化命名的子文件夹中查找.我看到了以下文章中描述的回退机制,但没有关于它如何被修改的线索:BCL团队关于ResourceManager的博客文章.

有谁有想法吗?这似乎是一个相对常见的在线问题(例如,Stack Overflow上的另一个问题:" ILMerge和本地化资源程序集 "),但我没有在任何地方找到任何权威答案.


更新1:基本解决方案

按照下面的casperOne的建议,我终于能够做到这一点.

我在这里提出解决方案代码,因为casperOne提供了唯一的答案,我不想添加自己的答案.

通过从"InternalGetResourceSet"方法中实现的Framework资源查找回退机制中拉出内容并使我们的同一组件搜索成为第一个使用的机制,我能够使它工作.如果在当前程序集中找不到资源,那么我们调用基本方法来启动默认搜索机制(感谢下面的@Wouter注释).

为此,我派生了"ComponentResourceManager"类,并且只覆盖了一个方法(并重新实现了一个私有框架方法):

class SingleAssemblyComponentResourceManager : 
    System.ComponentModel.ComponentResourceManager
{
    private Type _contextTypeInfo;
    private CultureInfo _neutralResourcesCulture;

    public SingleAssemblyComponentResourceManager(Type t)
        : base(t)
    {
        _contextTypeInfo = t;
    }

    protected override ResourceSet InternalGetResourceSet(CultureInfo culture, 
        bool createIfNotExists, bool tryParents)
    {
        ResourceSet rs = (ResourceSet)this.ResourceSets[culture];
        if (rs == null) …
Run Code Online (Sandbox Code Playgroud)

.net c# assemblies localization winforms

55
推荐指数
1
解决办法
2万
查看次数

如何转换C#.NET应用程序以支持多种语言?

我有一个C#应用程序,我需要转换为支持英语和西班牙语,是否有一种简单的方法来添加它,以后能够添加其他语言?

c# localization winforms

4
推荐指数
1
解决办法
2726
查看次数

标签 统计

c# ×2

localization ×2

winforms ×2

.net ×1

assemblies ×1