3 回答
TA贡献1712条经验 获得超3个赞
基本解决方案
遵循casperOne的建议,我终于能够完成这项工作。
我将解决方案代码放在问题中,因为casperOne提供了唯一的答案,我不想添加自己的答案。
通过将胆量从“ InternalGetResourceSet”方法中实现的Framework资源查找后备机制中剔除,并使我们的程序集搜索成为第一个使用的机制,我能够使其工作。如果在当前程序集中找不到该资源,则我们调用base方法来启动默认的搜索机制(由于下面的@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)
{
Stream store = null;
string resourceFileName = null;
//lazy-load default language (without caring about duplicate assignment in race conditions, no harm done);
if (this._neutralResourcesCulture == null)
{
this._neutralResourcesCulture =
GetNeutralResourcesLanguage(this.MainAssembly);
}
// if we're asking for the default language, then ask for the
// invariant (non-specific) resources.
if (_neutralResourcesCulture.Equals(culture))
culture = CultureInfo.InvariantCulture;
resourceFileName = GetResourceFileName(culture);
store = this.MainAssembly.GetManifestResourceStream(
this._contextTypeInfo, resourceFileName);
//If we found the appropriate resources in the local assembly
if (store != null)
{
rs = new ResourceSet(store);
//save for later.
AddResourceSet(this.ResourceSets, culture, ref rs);
}
else
{
rs = base.InternalGetResourceSet(culture, createIfNotExists, tryParents);
}
}
return rs;
}
//private method in framework, had to be re-specified here.
private static void AddResourceSet(Hashtable localResourceSets,
CultureInfo culture, ref ResourceSet rs)
{
lock (localResourceSets)
{
ResourceSet objA = (ResourceSet)localResourceSets[culture];
if (objA != null)
{
if (!object.Equals(objA, rs))
{
rs.Dispose();
rs = objA;
}
}
else
{
localResourceSets.Add(culture, rs);
}
}
}
}
要实际使用此类,您需要在Visual Studio创建的“ XXX.Designer.cs”文件中替换System.ComponentModel.ComponentResourceManager-并且每次更改设计表单时都需要执行此操作-Visual Studio会替换该类自动编码。(该问题在“ 自定义Windows窗体设计器以使用MyResourceManager ”中进行了讨论,但没有找到更优雅的解决方案-我在预构建步骤中使用fart.exe来自动替换。)
TA贡献1836条经验 获得超3个赞
另一个快速说明-使用ILMerge困扰我的一件事是它是附加的专有Microsoft工具,默认情况下未随Visual Studio一起安装,因此存在额外的依赖关系,这使得第三方上手有点困难与我的开源项目。
我最近发现了ILRepack,它是一种等效于开源(Apache 2.0)的工具,到目前为止,它对我也可以正常工作(直接替换),并且可以随项目源自由分发。
我希望这可以帮助某个人!
- 3 回答
- 0 关注
- 495 浏览
添加回答
举报