我在尝试将资源文件写入磁盘时遇到问题(所有资源文件都是同一项目和程序集的一部分)。
如果我添加
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();
}
但这似乎......错了......这是否是其他任何人都会这样做的,我确定我错过了一些东西,这样的任务很普遍,有更好的解决方案吗?
答案 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);
}
}
}