创建了一个类库,UserInfo.cs代码如下using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace Model
{
public class UserInfo
{
public virtual int ID { get; set; }
public virtual string UserID { get; set; }
public virtual string UserName { get; set; }
}
}
我想动态编译它在另外一个WinForm中,
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.IO;CSharpCodeProvider objCSharpCodePrivoder=new CSharpCodeProvider();
CompilerParameters paras = new CompilerParameters();
paras.GenerateExecutable = false; //编译成exe还是dll
//paras.ReferencedAssemblies.Add("System.dll");
paras.GenerateInMemory = false; //是否写入内存,不写入内存就写入磁盘
paras.OutputAssembly = "C:\\UserInfo.dll"; //输出路径
StreamReader sr = new StreamReader(@"C:\UserInfo.cs");
String txtStr = sr.ReadToEnd();CompilerResults result = objCSharpCodePrivoder.CompileAssemblyFromSource(paras, txtStr);为什么编译不成功?result的返回值错误:
未能加载文件或程序集“file:///C:\UserInfo.dll”或它的某一个依赖项。系统找不到指定的文件。
^怎么回事?UserInfo.dll不是应该生成出来的么?
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace Model
{
public class UserInfo
{
public virtual int ID { get; set; }
public virtual string UserID { get; set; }
public virtual string UserName { get; set; }
}
}
我想动态编译它在另外一个WinForm中,
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.IO;CSharpCodeProvider objCSharpCodePrivoder=new CSharpCodeProvider();
CompilerParameters paras = new CompilerParameters();
paras.GenerateExecutable = false; //编译成exe还是dll
//paras.ReferencedAssemblies.Add("System.dll");
paras.GenerateInMemory = false; //是否写入内存,不写入内存就写入磁盘
paras.OutputAssembly = "C:\\UserInfo.dll"; //输出路径
StreamReader sr = new StreamReader(@"C:\UserInfo.cs");
String txtStr = sr.ReadToEnd();CompilerResults result = objCSharpCodePrivoder.CompileAssemblyFromSource(paras, txtStr);为什么编译不成功?result的返回值错误:
未能加载文件或程序集“file:///C:\UserInfo.dll”或它的某一个依赖项。系统找不到指定的文件。
^怎么回事?UserInfo.dll不是应该生成出来的么?
using System.Reflection;
using System.Globalization;
using Microsoft.CSharp;
using System.CodeDom;
using System.CodeDom.Compiler; private string CreateCode()
{
StringBuilder sb = new StringBuilder();
//声明需要使用的命名空间。
sb.Append("using System;");
sb.Append("using System.Collections.Generic;");
sb.Append("using System.ComponentModel;");
sb.Append("using System.Data;");
sb.Append("using System.Drawing;");
sb.Append("using System.Text;");
sb.Append("using System.Windows.Forms;");
sb.Append(Environment.NewLine);
//将需要执行的功能this.code,字符串包装到一个类的函数里面。
sb.Append("namespace DynamicCodeGenerate");
sb.Append(Environment.NewLine);
sb.Append("{");
sb.Append(Environment.NewLine);
sb.Append(" public class HelloWorld");
sb.Append(Environment.NewLine);
sb.Append(" {");
sb.Append(Environment.NewLine);
sb.Append(" public void OutPut()");
sb.Append(Environment.NewLine);
sb.Append(" {");
sb.Append(Environment.NewLine);
sb.Append(this.code);
sb.Append(Environment.NewLine);
sb.Append(" }");
sb.Append(Environment.NewLine);
sb.Append(" }");
sb.Append(Environment.NewLine);
sb.Append("}");
//将所有声明的字符串返回给编译器使用。
string code = sb.ToString();
return code;
}
private void btnRun_Click(object sender, EventArgs e)
{
CodeDomProvider _CodeDomProvider = CodeDomProvider.CreateProvider("CSharp");
//提供对 C# 代码生成器和代码编译器的实例的访问
//CSharpCodeProvider _CSharpCodePrivoder = new CSharpCodeProvider();
//定义用于调用源代码编译的接口或使用指定编译器的 CodeDOM 树
//ICodeCompiler _ICodeCompiler = _CodeDomProvider.CreateCompiler(); //_CSharpCodePrivoder.CreateCompiler();
//表示用于调用编译器的参数,将所有需要使用的DLL和EXE文件添加打参数里面。
CompilerParameters _CompilerParameters = new CompilerParameters();
_CompilerParameters.ReferencedAssemblies.Add("System.dll");
_CompilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
_CompilerParameters.ReferencedAssemblies.Add("CodeDom.exe");
_CompilerParameters.ReferencedAssemblies.Add("System.Data.dll");
_CompilerParameters.ReferencedAssemblies.Add("System.Drawing.dll");
_CompilerParameters.GenerateExecutable = false;
_CompilerParameters.GenerateInMemory = true;
//表示从编译器返回的编译结果
//CompilerResults _CompilerResults = _ICodeCompiler.CompileAssemblyFromSource(_CompilerParameters, this.CreateCode());
//在CodeDomProvider 类中已经实现了ICodeCompiler类中的CompileAssemblyFromSource()方法,直接调用就可以了!
CompilerResults _CompilerResults =_CodeDomProvider.CompileAssemblyFromSource(_CompilerParameters, this.CreateCode());
if (_CompilerResults.Errors.HasErrors)
{
string ErrorMessage="";
foreach (CompilerError err in _CompilerResults.Errors)
{
ErrorMessage += err.ErrorText;
}
MessageBox.Show(ErrorMessage);
}
else
{
// 通过反射,调用HelloWorld的实例
Assembly _Assembly = _CompilerResults.CompiledAssembly;
//CreateInstance()从此程序集中查找某个类型,然后使用系统激活器创建它的实例
object _HelloWorld = _Assembly.CreateInstance("DynamicCodeGenerate.HelloWorld");
//发现方法的属性并提供对方法元数据的访问,获取OutPut()方法。
MethodInfo _MethodInfo = _HelloWorld.GetType().GetMethod("OutPut");
//执行objMI对象中的objHelloWorld对象中的函数。
_MethodInfo.Invoke(_HelloWorld, null);
}
}
CodeDomProvider CodeDomProvider = CodeDomProvider.CreateProvider("CSharp");
//CSharpCodeProvider objCSharpCodePrivoder=new CSharpCodeProvider();
CompilerParameters _CompilerParameters = new CompilerParameters();
/*
paras.GenerateExecutable = false; //编译成exe还是dll
//paras.ReferencedAssemblies.Add("System.dll");
paras.GenerateInMemory = false; //是否写入内存,不写入内存就写入磁盘
paras.OutputAssembly = "C:\\UserInfo.dll"; //输出路径
*/
_CompilerParameters.ReferencedAssemblies.Add("System.dll");
_CompilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
_CompilerParameters.ReferencedAssemblies.Add("CodeDom.exe");
_CompilerParameters.ReferencedAssemblies.Add("System.Data.dll");
_CompilerParameters.ReferencedAssemblies.Add("System.Drawing.dll"); StreamReader sr = new StreamReader(@"C:\UserInfo.cs");
String txtStr = sr.ReadToEnd(); CompilerResults result = CodeDomProvider.CompileAssemblyFromSource(_CompilerParameters, txtStr);
还是不行。
系统找不到指定的文件,是IO异常,不是应该是生成出来的么,应该新建啊
ICodeGenerator gen = provider.CreateGenerator();
StreamWriter sw = new StreamWriter("d:\\A.cs", false);ICodeGenerator gen = provider.CreateGenerator();
gen.GenerateCodeFromCompileUnit(compileunit, sw, new CodeGeneratorOptions());
dic.Add("CompilerVersion", "v3.5");
CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider(dic);
CompilerParameters paras = new CompilerParameters();
paras.GenerateExecutable = false; //编译成exe还是dll
//paras.ReferencedAssemblies.Add("System.dll");
paras.GenerateInMemory = true; //是否写入内存,不写入内存就写入磁盘
paras.OutputAssembly = "C:\\UserInfo.dll"; //输出路径
paras.ReferencedAssemblies.Add("System.dll");
paras.ReferencedAssemblies.Add(@"C:\WINDOWS\assembly\GAC_MSIL\System.Core\3.5.0.0__b77a5c561934e089\System.Core.dll");
StreamReader sr = new StreamReader(@"C:\UserInfo.cs");
String txtStr = sr.ReadToEnd();
CompilerResults result = objCSharpCodePrivoder.CompileAssemblyFromSource(paras, txtStr);
if (result.Errors.HasErrors)
{
string ErrorMessage = "";
foreach (CompilerError err in result.Errors)
{
ErrorMessage += err.ErrorText;
}
Console.WriteLine(ErrorMessage);
}
输出
“Model.UserInfo.ID.get”必须声明主体,因为它未标记为 abstract 或 extern“Model.
UserInfo.ID.set”必须声明主体,因为它未标记为 abstract 或 extern“Model.UserInfo
.UserID.get”必须声明主体,因为它未标记为 abstract 或 extern“Model.UserInfo.Use
rID.set”必须声明主体,因为它未标记为 abstract 或 extern“Model.UserInfo.UserNam
e.get”必须声明主体,因为它未标记为 abstract 或 extern“Model.UserInfo.UserName.
set”必须声明主体,因为它未标记为 abstract 或 extern
请按任意键继续. . .
IDictionary <string, string> dic = new Dictionary <string, string>();
dic.Add("CompilerVersion", "v3.5");
的确是会出这个错的,但加了之后不应该有错啊,我测试过成功了的
在原来的项目里编译,生成后把dll拿过来?
CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider(dic);这行会出错,CSharpCodeProvider不支持一个参数的重载,我在VS2008下则可以各位有经验的能不能给点动态编译的资料我去学习下?网上搜的那些文章大部分都看过了。比如编译出来的dll的版本号1.0.0怎么设置啊?
CompilerParameters一些有用的设置什么的,学习下
CompilerParameters一些有用的设置什么的,学习下?还有就是VS2008用3.5的语法,可不可以弄出2.0的.NetFrameWork的"通用"版本?因为现在安装3.5的机器不多,虽然我机上是3.5的运行库.
客户一般都是安装2.0的