创建了一个类库,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不是应该生成出来的么?

解决方案 »

  1.   


    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); 
                } 
            }
      

  2.   

    LS的也就是文本自己用StringBuilder写了下放进CreateCode中进行返回罢了,我是从文本中读入放进字符串,效果是一样的,现在根据楼上的代码我修改了如下:
    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);
    还是不行。
      

  3.   

    问题result异常依旧,很奇怪
    系统找不到指定的文件,是IO异常,不是应该是生成出来的么,应该新建啊
      

  4.   

    "C:\\UserInfo.dll" 改为 "D:\\UserInfo.dll" 试试。
      

  5.   

    CSharpCodeProvider provider = new CSharpCodeProvider();
    ICodeGenerator gen = provider.CreateGenerator();
    StreamWriter sw = new StreamWriter("d:\\A.cs", false);ICodeGenerator gen = provider.CreateGenerator();
    gen.GenerateCodeFromCompileUnit(compileunit, sw, new    CodeGeneratorOptions());
       
      

  6.   

    测试通过:            IDictionary<string, string> dic = new Dictionary<string, string>();
                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);
                }
      

  7.   


    输出
    “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
    请按任意键继续. . .
      

  8.   

    我的类难道不能编译?IDE是可以的啊...本来直接用OJ的代码编译,说缺少System.Linq,于是我把我类中的using System.Linq给去掉了,出现了上面的问题
      

  9.   

    小菜初来C#版块就受到.Net的各位牛人的欢迎,真是不胜荣幸啊
      

  10.   

    如果不加头两句
    IDictionary <string, string> dic = new Dictionary <string, string>();
    dic.Add("CompilerVersion", "v3.5");
    的确是会出这个错的,但加了之后不应该有错啊,我测试过成功了的
      

  11.   

    添加新类,把代码copy过去?
    在原来的项目里编译,生成后把dll拿过来?
      

  12.   

    oj用的是2008版的VS吧?2005的中,
    CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider(dic);这行会出错,CSharpCodeProvider不支持一个参数的重载,我在VS2008下则可以各位有经验的能不能给点动态编译的资料我去学习下?网上搜的那些文章大部分都看过了。比如编译出来的dll的版本号1.0.0怎么设置啊?
    CompilerParameters一些有用的设置什么的,学习下
      

  13.   

    我的确是在vs2008中通过的,如果用vs2005编译C#3.0以上语法不太可能吧
      

  14.   

    再说点问题各位有经验的能不能给点动态编译的资料我去学习下?网上搜的那些文章大部分都看过了。比如编译出来的dll的版本号1.0.0怎么设置啊? 
    CompilerParameters一些有用的设置什么的,学习下?还有就是VS2008用3.5的语法,可不可以弄出2.0的.NetFrameWork的"通用"版本?因为现在安装3.5的机器不多,虽然我机上是3.5的运行库.
    客户一般都是安装2.0的