Search code examples
c#.net-assemblyembedded-resourcestreamreader

C# application can not load embedded text resources


I can not read embedded resource text file. I keep getting this error when i start my C# application

    Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: stream
   at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen)
   at System.IO.StreamReader..ctor(Stream stream, Encoding encoding)
   at abcdefg.abcdefgh.LoadResource(String ResourcePath)
   at abcdefg.abcdefgh.<Main>b__0()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

This is the method:

public static string LoadResource(string ResourcePath)
{
    var assembly = Assembly.GetExecutingAssembly();
    using (var stream = assembly.GetManifestResourceStream(ResourcePath))
    {
        using (var reader = new StreamReader(stream, Encoding.UTF8))
        {
            return reader.ReadToEnd();
        }
    }
}

This is how am i compiling the executable using CODEDOM:

                    Dictionary<string, string> provOptions = new Dictionary<string, string>();
                provOptions.Add("CompilerVersion", "v4.0");
                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp", provOptions);

                CompilerParameters parameters = new CompilerParameters();
                parameters.ReferencedAssemblies.Add("System.Net.dll");
                parameters.ReferencedAssemblies.Add("System.Windows.dll");
                parameters.ReferencedAssemblies.Add("System.Net.Http.dll");
                parameters.ReferencedAssemblies.Add("System.Management.dll");
                parameters.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
                parameters.ReferencedAssemblies.Add("System.Data.dll");
                parameters.ReferencedAssemblies.Add("System.Deployment.dll");
                parameters.ReferencedAssemblies.Add("System.Xml.Linq.dll");
                parameters.ReferencedAssemblies.Add("System.Data.DataSetExtensions.dll");
                parameters.ReferencedAssemblies.Add("System.Data.dll");


                var assemblies = AppDomain.CurrentDomain
                        .GetAssemblies()
                        .Where(a => !a.IsDynamic)
                        .Select(a => a.Location);

                parameters.ReferencedAssemblies.AddRange(assemblies.ToArray());
                parameters.GenerateExecutable = true;
                parameters.OutputAssembly = Output;
                parameters.CompilerOptions = "/utf8output /warnaserror- /debug- /optimize+ /unsafe+ /target:exe /platform:x86";
                parameters.TreatWarningsAsErrors = false;
                parameters.EmbeddedResources.Add(resfile);
                CompilerResults results = provider.CompileAssemblyFromSource(parameters, mainScript);

The resource path format i am using is: abcdefg.Resource1.txt


Solution

  • I fixed it by using this code, it loops trough all resources and chooses that one i want:

    string[] resNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
        foreach (string resName in resNames)
        {
            if (resName == ("Resource1.txt"))
            {
                Assembly assembly = Assembly.GetExecutingAssembly();
                string resourcename = assembly.GetManifestResourceNames().Single(str => str.EndsWith(resName));
                Stream stream = assembly.GetManifestResourceStream(resourcename);
                StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                string output = reader.ReadToEnd();
                reader.Dispose();
                stream.Dispose();
            }
        }