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

本文关键字:资源 文本 图像 文件 | 更新日期: 2023-09-27 18:31:49

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

如果我添加

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();            
    }

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

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

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

更高效的是,Visual Studio为此支持设计器,因此您不必猜测需要传递的字符串。 使用"项目 + 属性"、"资源"选项卡。 单击"添加资源"按钮的下拉箭头,然后选择您的文件。 现在,可以使用变量名称引用代码中的资源。 喜欢:

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

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

这就是我使用的!希望它能帮助其他人。感觉有些黑客,但它有效!

    /// <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);
            }
        }
    }