Hi,
I am trying to compile dynamically generated C# source code. However, I am having trouble getting the code to work properly due to referenced assemblies not being found. I have tried setting the CompilerOption "/lib:path_to_find_assemblies" but then get a compiler error CS2008 No inputs specified.
I have set the CompilerParameter property GenerateInMemory to true, but the compiler still writes the assembly to disk.
Also it seems as though one can't specify where the generated assembly should be created.
Here is a snippet of my code:
CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
//setup compiler options
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("AnotherAssembly.dll");
options.OutputAssembly = name+".dll";
options.GenerateExecutable = false;
options.IncludeDebugInformation = false;
options.GenerateInMemory = true;
options.CompilerOptions = string.Format("/lib:{0}", baseDir);
//compile
CompilerResults results = compiler.CompileAssemblyFromFile(options, path);
where name = the assemblyName to be created, path = the path to the generated source file and baseDir = location to find the referenced assemblies.
Anyone able to assist here
Thanks.
Stefan

C# CodeCompiler errors
sspotts
Below is code for compiling code at runtime:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Diagnostics;
namespace CSWinCompiler
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Button button2;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.textBox2 = new System.Windows.Forms.TextBox();
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox2
//
this.textBox2.BackColor = System.Drawing.SystemColors.Control;
this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.textBox2.ForeColor = System.Drawing.SystemColors.WindowText;
this.textBox2.Location = new System.Drawing.Point(264, 56);
this.textBox2.Multiline = true;
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(240, 232);
this.textBox2.TabIndex = 2;
this.textBox2.Text = "";
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(16, 48);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(240, 240);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
this.textBox1.WordWrap = false;
//
// button1
//
this.button1.Location = new System.Drawing.Point(352, 296);
this.button1.Name = "button1";
this.button1.TabIndex = 1;
this.button1.Text = "Build";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(432, 296);
this.button2.Name = "button2";
this.button2.TabIndex = 1;
this.button2.Text = "Run";
this.button2.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(512, 325);
this.Controls.Add(this.button2);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler();
string Output = "Out.exe";
Button ButtonObject = (Button) sender;
textBox2.Text = "";
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
//Make sure we generate an EXE, not a DLL
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Data.dll");
parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
parameters.ReferencedAssemblies.Add("System.Collections.dll");
parameters.ReferencedAssemblies.Add("System.Data.dll");
parameters.ReferencedAssemblies.Add("System.ComponentModel");
parameters.ReferencedAssemblies.Add("System.Drawing");
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = false;
parameters.OutputAssembly = Output;
parameters.CompilerOptions = String.Concat("/lib:", @"C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322");
CompilerResults results = icc.CompileAssemblyFromSource(parameters,textBox1.Text);
if (results.Errors.Count > 0)
{
textBox2.ForeColor = Color.Red;
foreach(CompilerError CompErr in results.Errors)
{
textBox2.Text = textBox2.Text +
"Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
}
else
{
//Successful Compile
textBox2.ForeColor = Color.Blue;
textBox2.Text = "Success!";
//If we clicked run then launch our EXE
if (ButtonObject.Text == "Run") Process.Start(Output);
}
}
}
}
When I run this application and want to compile below
code, it displays
------
Line number 0, Error Number: CS0006, 'Metadata file 'System.Collections.dll' could not be found;
Line number 0, Error Number: CS0006, 'Metadata file 'System.ComponentModel' could not be found;
Line number 0, Error Number: CS0006, 'Metadata file 'System.Drawing' could not be found;
-------
Please, help me.
Sincerely,
Teymur
pipemx
I have amended my code to not specify the output assembly and no debug information but I still get the same error (fatal error CS2008: No inputs specified). I have checked all my parameters, the directories don't contain spaces, and I have also examined the Output property in the CompilerResults while Debugging, which shows the command-line string that is run as well as the output from the compiler. The command line string appears to be fine and when run manually from the command-line works.
I have isolated the problem to when the code is run from a console application. As unit test code run from VS.NET (using TestDriven.NET) or from Nunit GUI it works fine! I guess this means it could be an environment issue. I will check my environment variables (PATH etc) and see if I come up with anything. Anything else you can suggest
I am using Visual Studio .NET 2003, .NET 1.1 and Windows XP SP2.
Thanks.
Stefan
My code is now as follows:
public static Assembly Compile(string path, string refAssembly)
{
//create compiler instance
CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
//setup compiler options
string libDir = AppDomain.CurrentDomain.BaseDirectory;
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add(refAssembly);
options.GenerateExecutable = false;
//options.IncludeDebugInformation = false;
options.GenerateInMemory = true;
options.CompilerOptions = string.Format("/lib:\"{0}\"", libDir);
//compile
CompilerResults results = compiler.CompileAssemblyFromFile(options, path);
if(results.Errors.HasErrors)
{
//handle errors
......
throw new ApplicationException(....);
} else {
//return in-memory assembly
return results.CompiledAssembly;
}
}
The output produced is below (as copied directly from Visual Studio .NET debug locals):
[0] "C:\\Projects\\DotNet\\SAL\\FormulaTest\\bin\\Debug> \"c:\\windows\\microsoft.net\\framework\\v1.1.4322\\csc.exe\" /t:library /utf8output /R:\"System.dll\" /R:\"SAL.Server.dll\" /out:\"C:\\DOCUME~1\\burwitzs\\LOCALS~1\\Temp\\pe_0sg6n.dll\" /debug- /optimize+ /lib:\"C:\\Projects\\DotNet\\SAL\\FormulaTest\\bin\\Debug\\\" \"C:\\Projects\\DotNet\\SAL\\FormulaTest\\bin\\Debug\\_Formulas\\Formula_12345.cs\"" string
rclakin
Assembly CompileFile ( string strSrcFile )
{
string strBaseDir = @"<path to third-party assembly";
}
Michael Taylor - 10/18/05
Zano
Michael Taylor - 10/18/05
ProNovice
Thanks again for your help.