Search code examples
c#.net-assemblysystem.reflectioncodedomcsharpcodeprovider

Reference Embedded Resource from Codedom Compiled Exe


I am using CodeDom Compiler and Microsoft.CSharp, I am trying to embed a resource and call it. The reason I don't try to call properties is because I always get an error saying Properties does not exist in the current context. So I want to know if doing Parameters.EmbeddedResources.Add("C:/Users/User1/Music/sample.mp3"); is actually helpful or if I should be doing it another way. This is what I have now in the compiler source:

Extract("TestCompiler", "C:/Users/User1/Downloads", "", "Music.mp3");

private static void Extract(string NameSpace, string OutputDir, string InternalPath, string ResourceName){
            Assembly assembly = Assembly.GetCallingAssembly();
            using (Stream s = assembly.GetManifestResourceStream(NameSpace + "." + (InternalPath == "" ? "" : InternalPath + ".") + ResourceName))
            using (BinaryReader r = new BinaryReader(s))
            using (FileStream fs = new FileStream(OutputDir + "\\" + ResourceName, FileMode.OpenOrCreate))
            using (BinaryWriter w = new BinaryWriter(fs))
                w.Write(r.ReadBytes((int)s.Length));
        }

When I do this and run the compiled exe this is the exception/error I get:

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: input
   at System.IO.BinaryReader..ctor(Stream input, Encoding encoding, Boolean leaveOpen)
   at TestCompiler.Program.Extract(String NameSpace, String OutputDir, String InternalPath, String ResourceName)
   at TestCompiler.Program.Main(String[] args)

I also have tried doing Extract("TestCompiler", "C:/Users/User1/Downloads", "Resources", "Music.mp3"); but I get the same error.

Is calling a embedded resource possible or should I give up? I've been at this for 3 days.


Solution

  • To answer my own question, I had to get all of the resources by doing this:

    string[] Resources = Assembly.GetExecutingAssembly().GetManifestResourceNames();
    

    and to reference and extract them I did this:

    foreach(string Resource in Resources)
       WriteResources(Resources[Resource], "C:\\Test\\example.mp3");
    
    public static void WriteResources(string Name, string Output){
          using(var Resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(Name))
             using(var File = new FileStream(Output, FileMode.Create, FileAccess.Write))
                Resource.CopyTo(File);
    }
    

    Luckily I was able to finish my project after some solid days.