私のグループで作成したアプリケーションにスクリプト機能を統合することについて多くの進歩を遂げましたが、今はちょっと止まっています。C#スクリプトから外部アプリケーションメソッドを呼び出す
私たちが作成したデータ取得ソフトウェア(アプリケーション)は、スクリプト機能を備えたいと思っています。私は外部で書かれたスクリプトを読んでコンパイルできるクラスをアプリケーションに埋め込んでいます。たとえば、アプリケーションにリンクされていない.csファイルを作成し、実行時にファイルを呼び出して正常に実行することができます。
私のスクリプトの有用性を広げるために今私がしなければならないことは、スクリプト内のアプリケーション内の既存のメソッドを呼び出すことです。私は、次の例でこのすべてを説明しようとするでしょう:
ここで私は、アプリケーションが
ScriptFile.cs
を実行している間、私はいつでも変更すること自由だ私のスクリプトファイルを持っていますnamespace SimpleScripts
{
public class MyScriptMul5 : ScriptingInterface.IScriptType1
{
public string RunScript(int value)
{
System.Console.WriteLine("Hello World! This works!");
//NEED THIS: Code to call pre-existing method in application
}
}
}
申し訳ありませんが、この大規模なコードブロックはありますが、質問が発生した場合に備えてすべてを含めると思っていました。私がしたいのは、このスクリプトハンドラを通して実行している間に、上記のスクリプトでメソッドTestExternalCallを呼び出すことだけです。
ScriptHandler.cs
namespace ScriptingInterface
{
public interface IScriptType1
{
string RunScript(int value);
}
}
namespace ScriptingExample
{
public static class ScriptingEx
{
public static void StartScript()
{
string path = @"TestScript1.cs";
// Open the file to read from.
string readText = File.ReadAllText(path);
Assembly compiledScript = CompileCode(readText);
if (compiledScript != null)
{
RunScript(compiledScript);
}
}
static Assembly CompileCode(string code)
{
Microsoft.CSharp.CSharpCodeProvider csProvider = new Microsoft.CSharp.CSharpCodeProvider();
CompilerParameters options = new CompilerParameters();
options.GenerateExecutable = false;
options.GenerateInMemory = true;
options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
// Compile our code
CompilerResults result;
result = csProvider.CompileAssemblyFromSource(options, code);
if (result.Errors.HasErrors)
{
// Report back to the user that the script has errored
Console.WriteLine("Script has errored");
for (int i = 0; i < result.Errors.Count; i++)
{
Console.WriteLine("Error {0}: {1}", i+1, result.Errors[i]);
}
return null;
}
if (result.Errors.HasWarnings)
{
Console.WriteLine("Script has warnings");
}
return result.CompiledAssembly;
}
static void RunScript(Assembly script)
{
foreach (Type type in script.GetExportedTypes())
{
foreach (Type iface in type.GetInterfaces())
{
if (iface == typeof(ScriptingInterface.IScriptType1))
{
ConstructorInfo constructor = type.GetConstructor(System.Type.EmptyTypes);
if (constructor != null && constructor.IsPublic)
{
ScriptingInterface.IScriptType1 scriptObject = constructor.Invoke(null) as ScriptingInterface.IScriptType1;
if (scriptObject != null)
{
//Lets run our script and display its results
MessageBox.Show(scriptObject.RunScript(50));
}
}
}
}
}
}
public static void TestExternalCall1()
{
Console.WriteLine("Called successfully!");
}
}
}
は、ご質問があれば私に教えてください、とうまくいけば私は自分自身を明らかにしました。
もう少し説明できますか?私はRunScriptへのインタフェースを提供すれば、内部のメソッドを呼び出すことができます。 – spaderdabomb