Search code examples
referencefile-not-foundcsharpcodeprovider

CSharpCodeProvider how to reference current assembly


I'm trying to dynamically compile code using CSharpCodeProvider. In the referenced assemblies, I'm adding a reference parameter for typeof(Program).Assembly.CodeBase), as was suggested here, but it doesn't work. I still get an error saying

error CS0006: Metadata file 'file:///C:/Code/MyProject/bin/MyProject.DLL' could not be found;

A file by that name does exist - the only difference is that the file extension shows lowercase in file explorer (".dll"), but otherwise, the filename from the error message matches the name and path of the dll I want to reference.

Any idea why the compiler would fail to see the referenced dll in this case?
Here is the relevant section of my code:

        CompilerResults result = null;
        CompilerParameters parms = new CompilerParameters();
        parms.GenerateExecutable = false;
        parms.GenerateInMemory = true;
        parms.OutputAssembly = "MyOutputAssembly";
        parms.ReferencedAssemblies.Add("System.dll");
        parms.ReferencedAssemblies.Add("System.Data.dll");
        parms.ReferencedAssemblies.Add("mscorlib.dll");
        parms.ReferencedAssemblies.Add(typeof(Program).Assembly.CodeBase); // Reference the current assembly

        // Lock because CSharpCodeProvider can only compile the code once per time slot
        lock (lockCompile)
        {
            using (CSharpCodeProvider codeProvider = new CSharpCodeProvider())
            {
                result = codeProvider.CompileAssemblyFromSource(parms, new string[] { code.ToString() });
            }
        }

Solution

  • Try using typeof(Program).Assembly.Location instead of .CodeBase. The .Location property on the assembly will return a straight-up path to the actual file that is loaded, whereas .CodeBase returns the caonical location in URI form. I'm not sure but I think there might be scenarios related to loading remotely-hosted code where .Location doesn't give you anything and .CodeBase might give e.g. an http URI, but in your scenario, it sounds like your assembly is always going to be local, so you should always have a valid .Location value. :-)