How can I extract a file from an embedded resource and save it to disk?
I have found that the easiest way to do this is to use Properties.Resources
and File
. Here is the code I use (requires using System.IO
)...
For Binary files:File.WriteAllBytes(fileName, Properties.Resources.file);
For Text files:File.WriteAllText(fileName, Properties.Resources.file);
Copying embedded resource as file to disk in C#
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.
C# extract an embedded resource from assembly to a specific location in pc?
Scenario I (Your Scenario)
- You have a project that has an embedded resource like (images,txt,etc)
- You want to extract this file from your assembly and transfer it to another location
Scenario II
- You have Class Library project (dll) that has an embedded resource like (images,txt, etc)
- You load this dll in your main project and want to access the resources (image) in your dll
Usage
Important: Before using the Code
packages.config is an EmbeddedResource (Substitute it with the resource you are using)
Namespace
of my project is ConsoleApp (Substitute it with your namespace)
Main
static void Main(string[] args)
{
ResourceManager.GetResourceInfo("packages.config");
if (ResourceManager.resourceExists == false)
return;
//Loads packages.config in Bin/Debug
ResourceManager.LoadResource("packages.config");
}
ResourceManager.cs
class ResourceManager
{
public static bool resourceExists { get; set; } = false;
private static Stream resourceStream { get; set; }
public static void GetResourceInfo(string fileNameWithExtension)
{
//Substitut this with your Project Name
//Class Library Name AssistantLib > Resources > AssistantLib.dll
const string pathToResource = "ConsoleApp.Folder1.Folder2";
//The Dll that you want to Load
var assembly = Assembly.GetExecutingAssembly();
//var names = assembly.GetManifestResourceNames();
var stream = assembly.GetManifestResourceStream($"{pathToResource}.{fileNameWithExtension}");
if (stream == null)
return;
resourceExists = true;
resourceStream = stream;
}
public static void LoadResource(string newFileNameWithExtension)
{
if(File.Exists(newFileNameWithExtension))
{
Console.WriteLine("File already exists");
return;
}
using (Stream s = File.Create(newFileNameWithExtension))
{
Console.WriteLine("Loading file");
resourceStream.CopyTo(s);
}
}
}
Output
Package.Config in output folder
Extract embedded resources in C#
Not sure why the Python script can't be extracted.... couple points though:
I would recommend to use
Path.Combine()
to stick together path and file name - don't do this yourself, too many chances for error!Since those are (text-based) scripts, you could do the whole copying much simpler:
System.IO.Stream fs = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(currentResource);
string scriptContents = new StreamReader(fs).ReadToEnd();
File.WriteAllText(destFile, scriptContents);With this approach, you should be easily able to see in debugging whether or not the script is properly loaded from resources. If not - check your resource name etc. (is the script really set to "embedded" resource?). If you have subdirectories for your resources, be aware that the resource name will contain those subdirectories as part of the fully qualified name - but separated by a dot (
.
), not a backslash like a physical path!
I can I access an Embedded Resource and save it as a file?
You just open a stream, read the resource and do with it what you want:
using (Stream stream = assembly.GetManifestResourceStream(".../ConfigurationFiles/Defaults/Core.xml"));
{
// turn it to a XDocument and store it
XDocument doc = XDocument.Load(stream);
// ...
}
The path name to the resource is composed by:
<Assembly default namespace>.<path to the resource>.<resource name>
How to embed a file and then save it to a location?
Since you activate the resources you have already a ResourceManager
.Just use GetObject
method,get the bytes of your file and write the them to a new file with File.WriteAllBytes
:
var bytes = Properties.Resources.ResourceManager.GetObject("resourceName") as byte[];
File.WriteAllBytes("newFile.zip", bytes);
Get Embedded Resource
You need to add the file as a typed resource. Adding file just to Resources
folder does not generate resource wrapper property.
Then you can reference the file content by
Dim fileConent As Byte() = My.Resources.FileName
Replace the FileName with your file name. Intellisense will guide you.
Write file from assembly resource stream to disk
I'm not sure why you're using BinaryReader
/BinaryWriter
at all. Personally I'd start off with a useful utility method:
public static void CopyStream(Stream input, Stream output)
{
// Insert null checking here for production
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
then call it:
using (Stream input = assembly.GetManifestResourceStream(resourceName))
using (Stream output = File.Create(path))
{
CopyStream(input, output);
}
You can change the buffer size of course, or have it as a parameter to the method - but the main point is that this is simpler code. Is it more efficient? Nope. Are you sure you really need this code to be more efficient? Do you actually have hundreds of megabytes you need to write out to disk?
I find I rarely need code to be ultra-efficient, but I almost always need it to be simple. The sort of difference in performance that you might see between this and a "clever" approach (if one is even available) isn't likely to be a complexity-changing effect (e.g. O(n) to O(log n)) - and that's the type of performance gain which really can be worth chasing.
EDIT: As noted in comments, .NET 4.0 has Stream.CopyTo
so you don't need to code this up yourself.
How to Read an embedded resource as array of bytes without writing it to disk?
You are actually already reading the stream to a byte array, why not just stop there?
public static byte[] ExtractResource(String filename)
{
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
using (Stream resFilestream = a.GetManifestResourceStream(filename))
{
if (resFilestream == null) return null;
byte[] ba = new byte[resFilestream.Length];
resFilestream.Read(ba, 0, ba.Length);
return ba;
}
}
edit: See comments for a preferable reading pattern.
Related Topics
How to Add CSS Class to HTML Generic Control Div
ASP.NET Core 2.0-2.2 Kestrel Not Serving Static Content
ASP.NET - Problems with Static Selected Style for a Selected Page on the Menu
ASP.NET Adding Class to Current Menuitem
Set Gridview Backcolor to Color from Datatable
Remove CSS Class in Code Behind
Publishing a Website Is Not Updating My CSS Bundles
Binding Wpf Datagrid Cell Background Colour with Trigger
When Using Iis Express No CSS Applied on a Remote Pc
Webbrowser Control IE8 Compatibility Mode On/Off Switch
Firefox Browser Does Not Reload the Update CSS/Js Files
Read and Write File on Streamingassetspath
How to Install Android APK from Code in Unity
Copy Files from Resources/Streamingassets to Application.Persistentdatapath Upon Installation
A Method for Making Http Requests on Unity iOS
Simple iOS Bluetooth Data Transmission Using Unity