2

CodeDom で新しい .cs ファイルを作成していますが、後で CSharpCodeProvider でコンパイル/実行したいのですが、参照に問題があります。

コードは次のようになります。

        var provider = new CSharpCodeProvider();
        var compilerparams = new CompilerParameters(
            new[]
            {
                "First.dll",
                "Second.dll"
            })
        {
            GenerateExecutable = false,
            GenerateInMemory = true
        };
        CompilerResults results = provider.CompileAssemblyFromFile(compilerparams, _path);
        if (!results.Errors.HasErrors)
            return results.CompiledAssembly;
        var errors = new StringBuilder("Compiler Errors :\r\n");
        foreach (CompilerError error in results.Errors)
        {
            errors.AppendFormat("Line {0},{1}\t: {2}\n",
                error.Line, error.Column, error.ErrorText);
        }
        throw new Exception(errors.ToString());

「First.dll」と「Second.dll」は、生成された .cs ファイルと同じフォルダーに存在し、直接実行するとエラーが発生します。それらを自分のプロジェクトの bin ディレクトリに移動すると問題なく動作しますが、それらを分離したままにしておきます。

"First.dll" と "Second.dll" の絶対パス、または bin ディレクトリに移動する代わりに、すべての参照を含むディレクトリへのパスを設定することはできますか?

CompilerParameters を絶対パスに変更しようとしましたが、役に立ちませんでした。

4

1 に答える 1

1

この問題を解決する新しい解決策を見つけました。メモリ内で生成する代わりに、出力パスを設定し、このパスを返します。後でそれを使用したい場合は、Assembly.LoadFrom() でロードします (同じディレクトリ内のすべての参照 dll を使用します)。

サンプルコード、

アセンブリの生成方法:

    public string CompileCode()
    {
        var provider = new CSharpCodeProvider();
        var outputPath = Path.Combine(Path.GetDirectoryName(_path), "temp.dll");
        var compilerparams = new CompilerParameters(
            new[]
            {
                @"D:\path\to\referenced\dll",
                @"D:\path\to\referenced\dll2"
            }, outputPath);
        CompilerResults results = provider.CompileAssemblyFromFile(compilerparams, _path);
        var i = results.PathToAssembly;
        if (!results.Errors.HasErrors)
            return i;
        var errors = new StringBuilder("Compiler Errors :\r\n");
        foreach (CompilerError error in results.Errors)
        {
            errors.AppendFormat("Line {0},{1}\t: {2}\n",
                error.Line, error.Column, error.ErrorText);
        }
        throw new Exception(errors.ToString());
    }

そしてそれをロードするには:

Assembly assembly = Assembly.LoadFrom(path);
//Do stuff with assembly
于 2015-07-01T15:14:01.560 に答える