Copying embedded resource as file to disk in C#
I have an INF file saved as an embedded resource in my C# project. I am trying to save this file to a local location on demand. I am using this method.
public static void SaveResourceToDisk(string ResourceName, string FileToExtractTo)
{
Stream s = Ass开发者_JAVA技巧embly.GetExecutingAssembly().GetManifestResourceStream(ResourceName);
FileStream resourceFile = new FileStream(FileToExtractTo, FileMode.Create);
byte[] b = new byte[s.Length + 1];
s.Read(b, 0, Convert.ToInt32(s.Length));
resourceFile.Write(b, 0, Convert.ToInt32(b.Length - 1));
resourceFile.Flush();
resourceFile.Close();
resourceFile = null;
}
When I try to call this method (passing the resource name along with the namespace name), I get the error:
Object reference not set to an instance of an object
What am I doing wrong here?
You could call
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
And inspect which embedded resources are accessible. Then you can compare that against what you are passing in to see if you are indeed accomplishing what you expected to.
Also, you should consider the using keyword to dispose of your streams:
using(FileStream ResourceFile = new FileStream(FileToExtractTo, FileMode.Create))
{
//do stuff
}
Good luck.
This is the easiest way to save an embedded resource:
var stream = assembly.GetManifestResourceStream("name of the manifest resourse");
var fileStream = File.Create(@"C:\Test.xml");
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(fileStream);
fileStream.Close();
Unpacks all embedded resources within an assembly and saves them alongside the assembly containing this class while maintaining the directory structure. This code does not require you to know anything about the files contained within the assembly and is a more generic solution but it does assume that all files have file extensions.
public class EmbeddedResources
{
private bool isUnpacked = false;
public async Task EnsureUnpacked(string saveDirectory)
{
if (!this.isUnpacked)
{
var assembly = Assembly.GetExecutingAssembly();
var assemblyDirectory = Path.GetDirectoryName(assembly.Location);
foreach (var name in assembly.GetManifestResourceNames())
{
var stream = assembly.GetManifestResourceStream(name);
var stringBuilder = new StringBuilder();
var parts = name
.Replace(typeof(EmbeddedResources).Namespace + ".", string.Empty)
.Split('.')
.ToList();
for (int i = 0; i < parts.Count; ++i)
{
var part = parts[i];
if (string.Equals(part, string.Empty))
{
stringBuilder.Append("."); // Append '.' in file name.
}
else if (i == parts.Count - 2)
{
stringBuilder.Append(part); // Append file name and '.'.
stringBuilder.Append('.');
}
else if (i == parts.Count - 1)
{
stringBuilder.Append(part); // Append file extension.
}
else
{
stringBuilder.Append(part); // Append file path.
stringBuilder.Append('\\');
}
}
var filePath = Path.Combine(saveDirectory, stringBuilder.ToString());
using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
await stream.CopyToAsync(fileStream);
}
}
this.isUnpacked = true;
}
}
}
attach your file in your project. click on attached file.go to properties,set set Build Action to Embedded Resource, use file name in code like this: "YourProjectName.YourFileNameIWithExt"
I had an Excel file added into my Resources
and had no luck using other's solutions. This was due to the file itself is accessed as a byte[]
through the Properties.Resources
instead of picking up the string path routing.
So I simply ask the user for a saving path and then I use the System.IO.File.WriteAllBytes
method:
using (var save = new SaveFileDialog())
{
save.Title = "File path for saving the file";
save.FileName = "Excel file.xlsx";
save.Filter = "Excel files|*.xlsx;*.xls";
var dialog = save.ShowDialog();
if (dialog != DialogResult.OK)
return;
System.IO.File.WriteAllBytes(save.FileName, Resources.ExcelFile);
}
精彩评论