1

プログラムにテキストボックスがあります。テキストボックスには、実行する関数/メソッドの名前を記述したり、パラメーターを渡すことができます。これはすべて解析され、大きなスイッチブロックを介して、私のケースが満たされている場合は、その特定のケースのコードとパラメーターを渡します。

しかし、私が本当にやりたいのは、stringbuilderを使用してソースコードをビルドしてから実行することです。

これは私のstringbuilderで構築されたソースコードの例です。

 outlook outlooken = new outlook(appNwindow);

  outlooken.createNewEmail(scriptarray[i][1],scriptarray[i][2],
  scriptarray[i][3],scriptarray[i][4]);

stringbuilderを使用して文字列を作成することはまったく問題ありません。しかし、どうすればそれらを実行できますか?

私はたくさんのテストを行い、すべてを適切に配置することができましたが、コードが常にエラーを生成するため、何かが欠けていると思います...

これが私のソースコードです

 CodeDomProvider myCodeDomeProvider = CodeDomProvider.CreateProvider("CSharp");
 String [] referenceAssemblies = {"System.dll"};
 //  string myAssemblyName = "myAssembly.dll";
 CompilerParameters myCompilerparameters = 
 new CompilerParameters(referenceAssemblies);

        myCompilerparameters.GenerateExecutable = false;
        myCompilerparameters.GenerateInMemory = true;

  //*** Here's the sourcecode it want to compile
  string[] arr1 = new string[] { "outlook outlooken = new outlook(appNwindow);","outlooken.createNewEmail(scriptarray[i][1],scriptarray[i][2],scriptarray[i[3],scriptarray[i][4]);"};

        CompilerResults myResults = myCodeDomeProvider.CompileAssemblyFromSource(myCompilerparameters, arr1);
        string objectname = "testet";
        string method = "createNewEmail";
        object[] args = new object[2];

        args[0] = "to";
        args[1] = "CC";

        if (myResults.Errors.HasErrors)

         {
            StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
            foreach (CompilerError error in myResults.Errors)
            {
            errors.AppendFormat("Line {0},{1}\t: {2}\n",
            error.Line, error.Column, error.ErrorText);
            }

            throw new Exception(errors.ToString());
            }
            else
            {
            Assembly assem = myResults.CompiledAssembly;
            object instance = null;

            Type type = assem.GetType(objectname);
            MethodInfo miChk = type.GetMethod(method);

            if (!miChk.IsStatic)
            {
            instance = assem.CreateInstance(objectname);
            type = instance.GetType();
            }

            MethodInfo mi = type.GetMethod(method);

            mi.Invoke(instance, args);
            }

これらは、実行時に発生するエラーです。

追加情報:コンパイラエラー:

1、1行目:名前空間にフィールドやメソッドなどのメンバーを直接含めることはできません

1,25行目:予期されるクラス、デリゲート、列挙型、インターフェイス、または構造体

1、1行目:名前空間にフィールドやメソッドなどのメンバーを直接含めることはできません

1,41行目:識別子が必要です

1,59行目:識別子が必要です

1,77行目:識別子が必要です

1,95行目:識別子が必要です

4

1 に答える 1

4

CodeDomは、任意のステートメントをコンパイルして実行しません。コンパイルするコードは、ソースからC#ファイルを実行する場合と同様に、有効なC#コードである必要があります。

これは、ステートメントを名前空間+クラスにラップし、クラスのメソッド(静的である可能性があります)内に配置する必要があることを意味します。

基本的に、入力を通常のC#ファイルを作成し、コンパイラーを使用して.csファイルをコンパイルする場合と考えてください。入力には同じ「テキスト」が必要です。

于 2012-08-04T00:33:53.747 に答える