资源文件转换问题

时间:2012-06-13 01:41:21

标签: c# resources

以下是要求:

使用资源文件转换器实用程序将项目资源文件从一个版本迁移到另一个版本。(ConvertResx)

我创建了一个简单的Windows应用程序项目。在设计时设置本地化属性。在.resx文件中,localizable属性条目已使用“MetaData”属性设置。在资源文件转换期间,它会转换.resx文件中的所有条目,但是localizable属性属性设置为“Data”属性而不是“Metadata”属性。

UseResxDataNodes'类将数据和元数据属性条目放在同一个集合中。

ResXResourceReader reader = new ResXResourceReader(path0);

        reader.UseResXDataNodes = true;

为了检索元数据收集条目,我使用了以下代码

iDictionaryEnumerator7 = reader.GetMetadataEnumerator();

但无法使用“元数据”属性标记读取元数据属性(可本地化)。在资源文件转换后,它已在resx文件中使用“Data”标记设置。

你能否帮我解决这个问题,如何阅读元数据属性(来自.resx文件的设计时属性属性,并将引用的程序集迁移到最新版本并将其写入.resx文件)如何迁移.resx文件中的元数据属性条目。

此致 Sivaguru s

1 个答案:

答案 0 :(得分:5)

我在尝试将资源文件写入与原始格式相同的格式时遇到了同样的问题。经过一些搜索和试验/错误后,我想出了以下解决方案来正确写出元数据节点。

ResXResourceReader readerData = new ResXResourceReader(new StringReader(sw.ToString()));
ResXResourceReader readerMetaData = new ResXResourceReader(new StringReader(sw.ToString()));

//Flag to read nodes as ResXDataNode, instead of key/value pairs, to preserve Comments.
readerData.UseResXDataNodes = true;

ResXResourceWriter writer = new ResXResourceWriter(this.FilePath);

foreach (DictionaryEntry resEntry in readerData)
{
    ResXDataNode node = resEntry.Value as ResXDataNode;

    if (node != null)
    {
        DictionaryEntry metaDataEntry;

        //Check if node is metadata. The reader does not distinguish between 
        //data and metadata when UseResXDataNodes flags is set to true.
        //http://connect.microsoft.com/VisualStudio/feedback/details/524508/resxresourcereader-does-not-split-data-and-metadata-entries-when-useresxdatanodes-is-true
        if (IsMetaData(readerMetaData, resEntry, out metaDataEntry))
        {
            writer.AddMetadata(metaDataEntry.Key.ToString(), metaDataEntry.Value);
        }
        else
        {
            writer.AddResource(node);
        }
    }   
}

writer.Generate(); //write to the file
writer.Close();

readerData.Close();
readerMetaData.Close();

/// <summary>
/// Check if resource data is metadata. If so, return the metadata node.
/// </summary>
/// <param name="metaDataReader"></param>
/// <param name="resEntry"></param>
/// <param name="metaData"></param>
/// <returns></returns>
private static bool IsMetaData(ResXResourceReader metaDataReader, DictionaryEntry resEntry, out DictionaryEntry metaData)
{
    IDictionaryEnumerator metadataEnumerator = metaDataReader.GetMetadataEnumerator();

    while (metadataEnumerator.MoveNext())
    {
        if (metadataEnumerator.Entry.Key.Equals(resEntry.Key))
        {
            metaData = metadataEnumerator.Entry;
            return true;
        }
    }

    return false;
}