即时编译程序集

时间:2014-03-09 09:43:26

标签: c# activex csc

我有这段代码:

static void Main(string[] args)
{
    CompilerParameters cp = new CompilerParameters
    {
        GenerateInMemory = true,
        IncludeDebugInformation = false,

    };

    cp.ReferencedAssemblies.AddRange(new string[]{
        "System.dll",
        "System.Data.dll",
        "System.Xml.dll",
        "Microsoft.mshtml.dll",
        "System.Windows.Forms.dll"
    });

    Assembly _assembly = Assembly.GetExecutingAssembly();
    StreamReader _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("myprog.restext.txt"));

    string src = _textStreamReader.ReadToEnd();
    byte[] code = Convert.FromBase64String(src);

    src = Encoding.UTF8.GetString(code);

    CompilerResults cr = CSharpCodeProvider.CreateProvider("CSharp").
        CompileAssemblyFromSource(cp, src);
    Assembly asm = cr.CompiledAssembly;
    Type typ = asm.GetType("clicker.Program");
    MethodInfo method = typ.GetMethod("DoStart");
    method.Invoke(null, new[] { (object)args });
}

我发现FileNotFoundException因为CompileAssemblyFromSource返回相同的错误。来源使用 mshtml

然后我尝试使用csc.exe编译它,它说:

error CS0006. (no Metadata for "Microsoft.mshtml.dll")

我认为是因为mshtml是ActiveX库。所以问题是如何使用activeX mshtml组装源代码。

P.S。 Source没有错误,并且已成功从VS编译,但无法通过“即时”编译进行编译。

1 个答案:

答案 0 :(得分:3)

  

我发现FileNotFoundException

这是正常的,Microsoft.mshtml.dll是主互操作程序集。它不是.NET Framework的一部分,因此无法自动定位。它也不会在用户的机器上提供,必须安装PIA。

最好的方法是确保程序集存在于您的构建目录中,以便它随程序一起部署,并且始终可以找到。 Project + Add Reference,选择Microsoft.mshtml。从References节点中选择它,并将Isolated属性设置为False,将Local Local设置为True。重建并验证您的bin \ Debug目录中是否存在Microsoft.mshtml.dll。

修改代码以将完整路径名传递给文件。像这样:

    var referenceAssemblies = new List<string> {
        "System.dll",
        "System.Data.dll",
        "System.Xml.dll",
        "System.Windows.Forms.dll" 
    };
    var homedir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    var mshtml = Path.Combine(homedir, "Microsoft.mshtml.dll");
    referenceAssemblies.Add(mshtml);

    cp.ReferencedAssemblies.AddRange(referenceAssemblies.ToArray());