从资源写入文件,其中资源可以是文本或图像

时间:2013-09-17 13:56:42

标签: c# .net embedded-resource

我在尝试将资源文件写入磁盘时遇到问题(所有资源文件都是同一项目和程序集的一部分)。

如果我添加

var temp = Assembly.GetExecutingAssembly().GetManifestResourceNames();

以下列格式返回string[]

Gener.OptionsDialogForm.resources
Gener.ProgressDialog.resources
Gener.Properties.Resources.resources
Gener.g.resources
Gener.Resources.reusable.css
Gener.Resources.other.jpg

数组的最后2个是我想要的唯一2个文件,但我认为并不能保证始终如此。当代码被更改时,数组可以以另一个顺序通过,因此我无法明确地在给定索引处调用该项(temp[4]

所以,我可以做到

foreach (string item in Assembly
             .GetExecutingAssembly()
             .GetManifestResourceNames())
{
    if (!item.Contains("Gener.Resources."))
        continue;

    //Do whatever I need to do
}

但这太可怕了!我对这种方法面临另一个问题;这不会返回带有扩展名的文件名,只会返回Name,因此,我不知道扩展名是什么。

这是目前的代码

    public void CopyAllFiles()
    {
        var files = Resources.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentUICulture, true, true);
        //var temp = Assembly.GetExecutingAssembly().GetManifestResourceNames();

        foreach (DictionaryEntry item in files)
        {
            using (var resourceFileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Gener.Resources." + item.Key.ToString() + ".css")) // this won't work, I can't hard code .css as the extension could be different
            {
                Stream stream = new FileStream(this.DirPath, FileMode.Create, FileAccess.Write);
                resourceFileStream.CopyTo(stream);
                stream.Dispose();
            }             
        }
        files.Dispose();            
    }

但这似乎......错了......这是否是其他任何人都会这样做的,我确定我错过了一些东西,这样的任务很普遍,有更好的解决方案吗?

2 个答案:

答案 0 :(得分:3)

资源名称是可预测的,您可以将名称传递给Assembly.GetManifestResourceStream()方法。

更高效的是,Visual Studio支持设计人员,因此您无需猜测需要传递的字符串。使用Project + Properties,Resources选项卡。单击“添加资源”按钮的下拉箭头,然后选择您的文件。您现在可以使用变量名称来引用代码中的资源。像:

  File.WriteAllText(path, Properties.Resources.reusable);

请考虑在运行时将资源复制到文件的一切智慧。只需使用安装程序或XCopy复制文件一次即可获得完全相同的结果。具有显着优势的是,这些资源将不再占用内存地址空间,并且当您没有对目录的写访问权时,您将不会遇到麻烦。这对启用UAC很常见。

答案 1 :(得分:1)

这就是我用过的东西!希望它会帮助别人。感觉有些什么是黑客攻击,但它确实有效!

    /// <summary>
    /// Copies all the files from the Resource Manifest to the relevant folders. 
    /// </summary>
    internal void CopyAllFiles()
    {
        var resourceFiles = Assembly.GetExecutingAssembly().GetManifestResourceNames();

        foreach (var item in resourceFiles)
        {
            string basePath = Resources.ResourceManager.BaseName.Replace("Properties.", "");

            if (!item.Contains(basePath))
                continue;


            var destination = this._rootFolder + "\\" + this._javaScriptFolder + "\\" + item.Replace(basePath + ".", "");

            using (Stream resouceFile = Assembly.GetExecutingAssembly().GetManifestResourceStream(item))
            using (Stream output = File.Create(destination))
            {
                resouceFile.CopyTo(output);
            }
        }
    }