日期:2014-05-20  浏览次数:21087 次

类库的编译问题
创建了一个类库,UserInfo.cs

代码如下
C# code

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中,
C# code
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不是应该生成出来的么?

------解决方案--------------------
C# code

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