C# - 在项目之间共享资源文件

7
我想知道如何在两个(或多个)项目之间共享资源文件。具体而言,我有三个项目:
1. 开发项目(CF.NET),其中包含资源文件(包括所有定义)。 2. 我有两个其他项目,它们是空的,但链接到开发项目,每次只是不同的构建,因此当我修改开发项目时,这三个项目也会更新。(修改csproj文件。) 3. 问题是,资源文件怎么办?当我尝试从开发项目访问时,我可以获得所有资源,但当我尝试从另外两个项目中访问时,它会抛出“MissingManifestResourceException”异常。
你有什么解决方法吗?
谢谢。
[编辑]
这是我做的:
1. 创建一个名为“RealProject”的项目,其中包含所有代码(包括资源文件)。 2. 创建一个名为“LinkedProject”的项目,其中不包含任何内容(我将其中的所有文件都删除了,并将csproj文件修改为以下内容:
  <ItemGroup>
    <Compile Include="..\RealProject\**\*.cs" />
  </ItemGroup>

在LinkedProject目录中,我只有以下文件和文件夹:
[Directory] bin [Directory] obj [File ] LinkedProject.csproj
整个LinkedProject使用RealProject文件,只是不同的配置构建(请参见此处了解原因:C# - Code compiler for .NET & CF.NET)。
一旦进入该配置,我就无法访问来自RealProject的资源文件...
如果您需要屏幕截图或更详细的说明,请随时提出。
[编辑]
使用此代码,它可以工作,但是ResourceManager未在正确的程序集名称上加载,但应该存在更好的解决方案!
Assembly ass = Assembly.ReflectionOnlyLoadFrom(@"..\..\..\RealProject\bin\Debug\RealProject.dll");
ResourceManager manager = new ResourceManager("RealProject.Properties.Resources", ass);

[解决方案]

需要检查以下几点:

  • LinkedProject与RealProject有相同的命名空间
  • 将资源添加为链接
  • 清理所有项目解决方案
  • 重新构建项目

进行测试!

3个回答

7

尝试将资源文件作为链接添加到另外两个项目中,并确保在项目文件中定义的命名空间是相同的。


通过那个“被黑”的项目文件,你只包含了*.cs文件。如果你也包含*.resx文件会发生什么? - Daniel Hilgarth
@Arnaud F.:我不确定我的评论是否显示在您的收件箱中,所以我再次写信给您。 - Daniel Hilgarth
1
@Arnaud F.:命名空间不匹配怎么办?我认为,如果你的链接项目有一个像LinkedProject这样的命名空间,而你的主项目在其项目文件中配置了一个像MainProject这样的命名空间,那么这将导致错误。 - Daniel Hilgarth
它们有相同的命名空间 ;) - Arnaud F.
我简直不敢相信...我刚刚整理了所有的解决方案,重新构建并重试了一下,结果居然成功了! - Arnaud F.
显示剩余4条评论

1

尝试将其他项目中的现有文件作为链接添加。


我尝试的第一件事不起作用。(我的另外两个项目已经链接到第一个项目!) - Arnaud F.

0
在不同项目之间共享资源文件的问题在于,您在使用相同文件的所有项目中必须具有相同的根命名空间。
或者不需要。
您可以在运行时在 *Resources.designer.cs 文件中获取根命名空间。请注意注释中的相关答案链接。确保提交此内容并密切关注它,代码生成器会覆盖它,这将破坏其通用性。我使用 XML 文档注释来提醒自己正在发生什么,如果代码生成器将其删除,我将在提交差异中看到它。
/// <summary> Returns the cached ResourceManager instance used by this class.  </summary>
/// <remarks> DO NOT commit any version of this file the tool overwrites, it will break it for other projects</remarks>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
    get {
        if (object.ReferenceEquals(resourceMan, null)) 
        {
            // https://dev59.com/zHM_5IYBdhLWcg3wjj6r#1329631 https://dev59.com/HG445IYBdhLWcg3wZJYn#51978052  
            Assembly thisAssembly = typeof(/*thisClassName*/).Assembly;
            // you need a class called "App", or just change the name on the next line to one you have in the root namespace
            var apps = thisAssembly?.GetTypes().Where(t => t.Name == "App");

            if (apps.Count() != 1)
                throw new InvalidOperationException($"Too Many App classes. Count: {apps.Count()}, Apps: {apps}");
            
            Type appType = apps.FirstOrDefault();
            string ns = appType.Namespace;
            global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager($"{ns}.OtherNames.Spaces.thisClassName", typeof(thisClassName).Assembly);
            resourceMan = temp;
        }
        return resourceMan;
    }
}

感谢您回答一个9年前的帖子 ;) - Arnaud F.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接