Execute ScriptCS from C # Application

Background

I am creating a C # app that runs some status checks (checks nagios style I think).

What I ideally want is this C # application to look at a specific directory and just compile / execute the scripts inside it and act on the results (for example, send email alerts for status check failures).

I would expect the script to return an integer or something (for example), and that integer would indicate the weather when the status check succeeded or failed.

Values ​​returned back to C # application.

0 - Success
1 - Warning
2 - Error

      

When I first asked this question, I thought it was a job for MEF, but it would be much more convenient to create these "status checks" without having to build a project or compile anything, just dragging and dropping scripts within the folder seems more attractive.

So my questions

  • Is there any documentation / samples on using a C # app and scripts together (google doesn't have much of me)?

  • Is this a use case for scripting or was it never intended to be used like this?

  • Wouldn't it be easier if just create your own solution using roslyn or some kind of dynamic compilation / execution? (I have very little experience with scriptsc)

+3


source to share


4 answers


I found some simple examples on how to do this:

Loading a script from a file on disk and running it: https://github.com/glennblock/scriptcs-hosting-example

A website where you can submit the code and it will return the result: https://github.com/filipw/sample-scriptcs-webhost



Here's an example of loading a script file, running it, and returning the result:

public dynamic RunScript()
{
    var logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    var scriptServicesBuilder = new ScriptServicesBuilder(new ScriptConsole(), logger).
        LogLevel(LogLevel.Info).Cache(false).Repl(false).ScriptEngine<RoslynScriptEngine>();

    var scriptcs = scriptServicesBuilder.Build();

    scriptcs.Executor.Initialize(new[] { "System.Web" }, Enumerable.Empty<IScriptPack>());
    scriptcs.Executor.AddReferences(Assembly.GetExecutingAssembly());

    var result = scriptcs.Executor.Execute("HelloWorld.csx");

    scriptcs.Executor.Terminate();

    if (result.CompileExceptionInfo != null)
        return new { error = result.CompileExceptionInfo.SourceException.Message };
    if (result.ExecuteExceptionInfo != null)
        return new { error = result.ExecuteExceptionInfo.SourceException.Message };

    return result.ReturnValue;
}

      

+3


source


Question 2: A scripting language can work well in this situation if you know a little about them.



Question 3: Personally Id uses CS-Script in its well-kept condition and there is a lot of documentation for it

+2


source


Sorry if I digress a little, but the question sparked my imagination and I thought ...

<s> IMMO scriptcs are more of a scripting environment, in itself, a bit like NodeCs ... It doesn't need anything to create a scripting environment out of the box. But as far as I could see. does not provide a managed api for a .net application. Of course, I could be wrong and it would be a question of finding the source, because from the docs I could not find a link either,

It seems to me that you are better off integrating the Roslyn api your self.

EDIT : I was wrong, ScriptCs scriptcs.hosting Nuget is the entry point and I see it as Glimpse here and MakeSharp did it;

But there is EdgeJs , out of the box gives you pretty much what you want, but the scripts will be Javascripts in NodeJs, but that doesn't seem to be what you want.

What if you try to load C # scripts directly from Edge, it can compile python, F #, C #, csx ... But it also does it from Node env, not .net (or am I missing something? )

Anyway ... it occurred to me that you can load Edge from .Net load Edge again from Node and invoke a .Net script that in turn will return something to .Net again.

It looks like overkill, but so nicely isolated that it might be worth trying. and besides, some tweak is not much to encode it.

I have uploaded the experiment to GitHub .

+1


source


Question 1. I made an (ugly) example of an integration test running ScriptCS from C # with System.Diagnostics.Process.Start () (in this case it uses Powershell) I have to answer your first question, which I hope.

    [Test, Explicit]
    public void RunScriptCsFile_FilePrintsTheValue2_StreamIsParsedCorrectly() {
        var scriptFile = @"C:\Projects\test-project\test-project.Tests\test-file.csx";
        var param = string.Format("scriptcs {0}", scriptFile);
        Process executeScript = new Process {
            StartInfo = new ProcessStartInfo {
                FileName = "powershell.exe",
                Arguments = param,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            }
        };

        executeScript.Start();
        var value = -1;
        while (!executeScript.StandardOutput.EndOfStream) {
            string line = executeScript.StandardOutput.ReadLine();
            if (int.TryParse(line, out value)) {
                Assert.AreEqual(2, value);
            }
        }
    }

      

Test-file.csx contains Console.WriteLine("2");

an example error for your case.

Question 3. I did a similar thing with Shovel ScriptPack for ScriptCS. It might be worth checking out.

+1


source







All Articles