2016-04-18 28 views
2

ユーザーがvbスクリプトやjavascriptでカスタマイズを追加できるようになったアプリケーションをいくつか見てきました。これの重い例は、vbscriptによるオフィスアドオンや、RubyスクリプティングによるRPGメーカーです。私はこの質問を知っている私は、ユーザーがしようと、すべての実行時のいくつかのスクリプト言語でいくつかのカスタムルールを書いてみましょうし、Webページ私のアプリにユーザースクリプトエンジンを追加する

を提出/保存するために、私のアプリの一つにオプションを追加したいた

私はまだこのタイプの問題を解決するためにどこから始めるべきかわかりません。私は、これを試みる際に考慮すべきことがたくさんあることを知っています。

正しい方向に指摘してください。

+0

ユーザーはどのレベルの言語やプログラミングを理解していますか?言い換えると、あなたのエンジン(およびその言語)がどれくらい前進することを期待していますか? –

+0

スクリプト作成のアドオンは、プログラミングを知っているITスタッフに、より多くの情報を提供します。 Visual Basicはプロジェクトマネージャが望むものです – Atomhax

+0

[Roslynプロジェクト](https://github.com/dotnet/roslyn)を見てください。私はそれがスクリプトホストとして使用できると信じています。それは好きに見える[他の人は既に同様のためにRoslynを使っている](http://stackoverflow.com/questions/11159007/roslyn-visualbasic-scriptengine-doesnt-recognize-hostobject-written-on-c-sharp)。 –

答えて

1

コーディングをクライアント側にしたい場合は、JavaScriptコードを使用して簡単にeval(userCode)のusercodeが文字列である場合にのみ使用できます。

c#を使用してサーバー側でユーザーのコードを実行する場合は、ライブラリMicrosoft.CSharpおよびSystem.CodeDom.Compilerを持つ組み込みコンパイラを使用できます。それはそのように行うことができます。

string code = @" 
    using System; 

    namespace First 
    { 
     public class Program 
     { 
      public static void Main() 
      { 
      " + 
       "Console.WriteLine(\"Hello, world!\");" 
       + @" 
      } 
     } 
    } 
"; //Assume this is the code the client gave you 
CSharpCodeProvider provider = new CSharpCodeProvider(); 
CompilerParameters parameters = new CompilerParameters(); 

parameters.GenerateInMemory = true; //You can add references to libraries using parameters.ReferencedAssemblies.Add(string - name of the assembly). 

CompilerResults results = provider.CompileAssemblyFromSource(parameters, code); //Compiling the string to an assembly 

if (results.Errors.HasErrors) 
{ 
    StringBuilder sb = new StringBuilder(); 

    foreach (CompilerError error in results.Errors) 
    { 
     sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText)); 
    } 

    throw new InvalidOperationException(sb.ToString()); 
} //Error checking 

Assembly assembly = results.CompiledAssembly; 
Type program = assembly.GetType("First.Program"); //Getting the class object 
MethodInfo main = program.GetMethod("Main"); //Getting the main method to invoke 

main.Invoke(null, null); //Invoking the method. first null - because the method is static so there is no specific instance to run in, second null tells us there are no parameters. 

コードスニペットは、CodeProjectのから取った:http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime

は、それが助けを願って!

3

サポートしたい言語に応じていくつかのオプションがあります。 VBScriptはMSScriptControlを使用して実行でき、C#はMicrosoft.CSharpを使用して実行できます。

ここでは、C#スクリプトをデータベースから取り出して実行した簡単な例を示します。これは文字列を取り込むだけなので、引数をコレクションまたは異なるデータ型にしたい場合は調整する必要があることに注意してください。

public class Transform 
{ 
    public static string Execute(string firstName) 
    { 
     return "Test"; 
    } 
} 

この1つの注意点は、あなたがクラスに名前を付ける必要があるだろうということである「トランスフォーム」と「実行」以来のたびに実行するための方法:

value = CreateTransformMethodInfo(_script.ScriptBody).Invoke(null, args.Select(x => x.Value).ToArray()); //args would be the arguments in your script 

public static MethodInfo CreateTransformMethodInfo(string script) 
    { 
     using (var compiler = new CSharpCodeProvider()) 
     { 
      var parms = new CompilerParameters 
      { 
       GenerateExecutable = false, 
       GenerateInMemory = true, 
       CompilerOptions = "/optimize", 
       ReferencedAssemblies = { "System.Core.dll" } 
      }; 

      return compiler.CompileAssemblyFromSource(parms, script) 
       .CompiledAssembly.GetType("Transform") 
       .GetMethod("Execute"); 
     } 
    } 

その後、実際のスクリプトは次のようになります実行するメソッドをコンパイルするときにこれら2つの値を使用することがわかります。 「実行中の」クラスとメソッドがTransform/Executeのままであれば、ヘルパークラスやメソッドに名前を付けることもできます。

関連する問題