Using CodeDOM I have something like this:
CompilerParameters parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
parameters.ReferencedAssemblies.Add("System.Data.Linq.dll");
parameters.ReferencedAssemblies.Add("System.Xml.Linq.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");
and when I run a program, this is the the error I get for the last three DLLs, the first two (System.DLL and System.Windows.Forms.DLL ) have no problem and error but as soon as I add those last three lines to load those DLLs too, then I get errors like the one in the picture.
So weird and annoying and couldn't find a way to fix it.
Thanks.
oh Wow! it was tricky!
It doesn't care what is the Target Platform that Visual Studio is set on, what it looks at is its own CodeProvider class. Previously I was using its default constructor. But it also has another constructor that takes a Dictionary parameter. In this parameter we are specifying what version of .NET should be used. So instead of just creating a new CodeProvider object I should do it like this:
Dictionary<string, string> compilerInfo = new Dictionary<string, string>();
compilerInfo.Add("CompilerVersion", "v3.5");
CSharpCodeProvider codeProvider = new CSharpCodeProvider(compilerInfo);
Now it works.
Related
Suppose Project Main has a reference to Project Ref. In Main, I have defined a CSharpCodeProvider and use it to compile code at runtime.
var provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
var parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("System.dll");
// Rest of the referenced assemblies.
The code which is compiled at runtime, might require a newer version of Project Ref to run correctly. So I tried to add the new Ref.Dll in a relative subfolder (plugins):
parameters.ReferencedAssemblies.Add(#"d:\project-output-path\plugins\Ref.dll");
I have also added the following:
AppDomain.CurrentDomain.AppendPrivatePath("plugins");
Problem is when I try to compile the script dynamically, the Ref.dll in the main folder is being used and causes error.
So, What would be the best way to reference the new Ref project only for my script?
P.S. I really prefer not having to create another AppDomain since the dynamically executing code is coupled with the code loaded in current AppDomain and cannot be separated.
I would like to know, how can i assign version numbers to dynamically created dlls. I have a mini application that creates dlls for my end users. But currently, all the dlls created are having 0.0.0.0 as their version numbers.
And it is difficult to keep track of the latest one. Is there are way to assign version numbers to dynamically created dlls. I tried searching the net but no avail.
Please do advise. I am using the following code create the dlls.
// Setup for compiling
var provider_options = new Dictionary<string, string>
{
{"CompilerVersion","v3.5"}
};
var provider = new Microsoft.CSharp.CSharpCodeProvider(provider_options);
var compiler_params = new System.CodeDom.Compiler.CompilerParameters();
string outfile = #"D:\EDUnit.dll";
compiler_params.OutputAssembly = outfile;
compiler_params.GenerateExecutable = false;
compiler_params.ReferencedAssemblies.Add("System.dll");
// Compile
var results = provider.CompileAssemblyFromSource(compiler_params, strbase)
You need to assign it to your source code file using reflection attributes. The code provider will look for it, extract it and add the required metadata. Decorate your source class as follows
using System.Reflection;
[assembly: AssemblyVersion("2.1.0.0")]
[assembly: AssemblyFileVersion("2.1.0.0")]
public class Your_Class{}
I need shell32 in my program to create a shortcut.
This is my code:
var compiler = new CSharpCodeProvider();
var Params = new System.CodeDom.Compiler.CompilerParameters
{
GenerateExecutable = true,
OutputAssembly = outputName,
ReferencedAssemblies = {
"System.dll",
"System.Core.dll",
"System.Windows.Forms.dll",
"System.Drawing.dll",
#"C:\Windows\System32\Shell32.dll"
}
};
Doing this, I get an error:
Metadata file C:\Windows\System32\Shell32.dll could not be opened. An attempt was made to load a program with incorrect format.
Found nothing while searching.. I wasn't even sure what to search for :/
How would I go about doing this?
Shell32.dll (Windows file systems don't care about case, so "s" or "S" shouldn't matter) is not a .NET assembly and thus can't be treated as such.
If you want to call functions exported from non-.NET libraries, you should use the DllImportAttribute.
I had the same problem and just solved it.
Add the following to your referenced Assemblies list:
ReferencedAssemblies.Add("Interop.Shell32.dll");
So I have a CodeDOM compiler written in C# that's supposed to compile another application based on one of its resources. How would I change the target .NET framework of the resource (or of the outputted executable of the compiler)?
You could pass options to the compiler using the following constructor:
var providerOptions = new Dictionary<string, string>();
providerOptions.Add("CompilerVersion", "v3.5");
var compiler = new CSharpCodeProvider(providerOptions);
...
You would need to specify it in a dictionary of settings for the compiler, such as:
var settings = new Dictionary<string,string>();
settings.Add("CompilerVersion", "v3.5");
var compiler = new CSharpCodeProvider(settings);
Unsurprisingly, Google already brings up a couple of examples of this, too; here and here.
I'm stuck on run-time compilation and CodeDom.
Here's a simplified example of what I have so far.
public static void Testing()
{
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
string Output = "Out.exe";
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Drawing.Dll");
parameters.ReferencedAssemblies.Add("System.Windows.Forms.Dll");
parameters.CompilerOptions = "/t:winexe";
string[] text = new string[] { #"C:\MyProject\Test.cs", #"C:\MyProject\Test.Designer.cs",
#"C:\MyProject\Program.cs"};
CompilerResults results = codeProvider.CompileAssemblyFromFile(parameters, text);
Process.Start(Output);
}
It works perfectly alright, and loads the Test form.
But! I need to pass a parameter to this Test form (a list of Panel controls) to populate the form.
How can I do this? Maybe, I am looking in the wrong direction, and it has to be done in a different way?
Thanks a lot in advance!
EDIT
In the end, I give up on CodeDom and used Mono.Cecil instead, injecting .exe file with information from my main program.
What you are doing is compiling an executable assembly then starting it in another process.
If you want to pass it information, command line arguments are one option. However, passing a .Net object on the command line will not work.
If you want to pass somthing managed you will have to use your new assembly with some late binding and pass your object to the constructor perhaps, rather depends what the code you are compiling accepts, if you have that at design time ...
Are you re-writing Visual Studio?