从外部dll加载资源,并确定资源类型

时间:2014-08-11 15:27:01

标签: c# embedded-resource

我有一个C#应用程序,我们所有资源都在一个库中。这基本上是几个文件夹,每个文件夹中都有一个或多个.resx文件。

在大多数情况下,.resx文件都有字符串资源。少数人拥有文件资源。

我有一项任务是通过这些字符串资源并对它们做些什么。只是字符串,而不是文件。

目前,我可以从单独的dll加载资源:

var asm = System.Reflection.Assembly.LoadFrom("External.Resources.dll");

string[] strings = asm.GetManifestResourceNames();

foreach (var s in strings)
{
    var rm = new ResourceManager(s, asm);

    var rs = rm.GetResourceSet(CultureInfo.CurrentCulture, true, true);

    foreach (DictionaryEntry de in rs)
    {
        var val = de.Value.ToString();
        var key = de.Key.ToString();
    }
}

不幸的是,我没办法告诉资源是什么。如果它是一个文件,则Value将只包含该文件的文本。

如何检查值是来自资源文件的字符串还是文件(文本)?

3 个答案:

答案 0 :(得分:3)

如果要获取原始资源类型,则必须访问原始资源对象。它将具有特定类型的静态属性;例如文件将是byte [],字符串为字符串等。

var asm = System.Reflection.Assembly.LoadFrom("External.Resources.dll");
string[] strings = asm.GetManifestResourceNames();

foreach (var s in strings)
{
    var rm = new ResourceManager(s, asm);

    // Get the fully qualified resource type name
    // Resources are suffixed with .resource
    var rst = s.Substring(0, s.IndexOf(".resource"));
    var type = asm.GetType(rst, false);

    // if type is null then its not .resx resource
    if (null != type)
    {
        var resources = type.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        foreach (var res in resources)
        {
            // collect string type resources
            if (res.PropertyType == typeof(string))
            {
                // get value from static property
                string myResourceString = res.GetValue(null, null) as string;
            }
        }
    }

}  

答案 1 :(得分:1)

LINQ版本的“循环代码”代码应如下所示:

<!DOCTYPE html>
<!--esse extends significa que ele vai entrar no bloco definido no arquivo base.html-->
{% extends "tweets/base.html" %}
<!--definicao dos blocos, ou seja, tera o mesmo header, body ..., o que muda eh o content-->    
{% block content %}
<div class="row clearfix">
    <div class="col-md-12 column">
        <!-- a classe well ou wellbox, da o efeito de insercao-->
        {% for tweet in tweets %}
        <div class="well">
            <span>{{ tweet.text }}</span>
        </div>
        {% endfor %}
    </div>
</div>
{% endblock %}

投票“循环代码”回答不是我的。我的代码是使用Resharper从他的原始代码开始创建的,我只是做了一些更改并删除了一条无用的指令:

 var asm = System.Reflection.Assembly.LoadFrom("External.Resources.dll");
 string[] strings = asm.GetManifestResourceNames();
 string myResourceString=null;
  foreach (var res in from s in strings
                                select s.Substring(0, s.IndexOf(".resource"))
                                into rst
                                select asm.GetType(rst, false)
                                into type
                                where null != type
                                select type.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
                                into resources
                                from res in resources
                                where res.PropertyType == typeof(string)
                                select res)
        {
            myResourceString = res.GetValue(null, null) as string;
        }

答案 2 :(得分:0)

根据您的代码,最直接的方法是调用ResourceSet.GetString(de.Key)并为非字符串资源捕获InvalidOperationException。效率不是很高,但我认为你在这里建立一个缓存,所以这是一次性的成本。