Search code examples
c#.netembedded-resource

Write from Resource to file where resource could be text or image


I'm having a problem trying to write my resource files to disk (all resource files part of the same project and assembly).

If I add

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

This returns a string[] in the following format

Gener.OptionsDialogForm.resources
Gener.ProgressDialog.resources
Gener.Properties.Resources.resources
Gener.g.resources
Gener.Resources.reusable.css
Gener.Resources.other.jpg

The last 2 of the array are the only 2 files I want but I assume it's not a guarantee that this will always be the case. The array could come through in another order as code is changed so I cannot explicity call the item at a given index (temp[4])

So, I could do

foreach (string item in Assembly
             .GetExecutingAssembly()
             .GetManifestResourceNames())
{
    if (!item.Contains("Gener.Resources."))
        continue;

    //Do whatever I need to do
}

But this is just horrible! I face another problem with this approach; This doesn't return the file name with the extension, just the Name and as such, I have no idea what the extension is.

This is the code as it currently is

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

But this seems... wrong... Is this how any one else would do this, I'm sure I'm missing something and such a task is common that there is a better solution?


Solution

  • This was what I used! Hopefully it will help others. It feels some what hacking, but it works!

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