2

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

如果我添加

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

这将返回string[]以下格式的 a

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

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

4

2 回答 2

3

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

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

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

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

于 2013-09-17T16:04:57.863 回答
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);
            }
        }
    }
于 2013-10-21T07:28:26.627 回答