3

let's assume we have a *.js file includeded in our C# UWP App project and we want to be able to execute function included in this file.

sample JS function:

function myFunction(p1, p2) {
return p1 * p2;              // The function returns the product of p1 and p2

}

sample C# code:

public class SampleObject
{
    public SampleObject(int a, int b)
    {
        var evaluated = <<< do some magic and get myFuction(a,b) here >>>
    }
}

Is there any way other that keeping some dummy WebView with our JS loaded and calling myFunction from it? I've read about Chakra that looks like something that should do the trick, but I don't know how to use it the way I want. Any few-lines sample?

2
  • Maybe you can add in the question title that you don't want to use a webview for that. Commented Jan 24, 2017 at 15:22
  • good point, changed title Commented Jan 24, 2017 at 15:35

2 Answers 2

1
  1. I'd use cscript.exe to run your JavaScript - see https://technet.microsoft.com/en-us/library/bb490887.aspx for information regarding this.
  2. Use the System.Diagnostics.Process object to call cscript.exe
  3. Pass the path to your JavaScript file using a ProcessStartInfo object.
  4. Set up events to capture output from the StandardOutput and StandardError channels. Note that not everything returned by StandardError is necessarily an error. I've created a wrapper to the Process class for convenience called cManagedProcess:

    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using System.Threading;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string sScriptPath = @"C:\temp\test.js";
                File.WriteAllText(sScriptPath, @"
    //Your JavaScript goes here!
    WScript.Echo(myFunction(1, 2));
    
    function myFunction(p1, p2) {
        return p1 * p2; // The function returns the product of p1 and p2
    }
    ");
    
                var oManagedProcess = new cManagedProcess("cscript.exe", sScriptPath);
                int iExitCode = oManagedProcess.Start();
    
                Console.WriteLine("iExitCode = {0}\nStandardOutput: {1}\nStandardError: {2}\n", 
                    iExitCode, 
                    oManagedProcess.StandardOutput,
                    oManagedProcess.StandardError
                    );
    
                Console.WriteLine("Press any key...");
                Console.ReadLine();
            }
        }
    
        public class cManagedProcess
        {
            private Process moProcess;
    
            public ProcessStartInfo StartInfo;
    
            private StringBuilder moOutputStringBuilder;
            public string StandardOutput
            {
                get
                {
                    return moOutputStringBuilder.ToString();
                }
            }
    
            private StringBuilder moErrorStringBuilder;
            public string StandardError
            {
                get
                {
                    return moErrorStringBuilder.ToString();
                }
            }
    
            public int TimeOutMilliSeconds = 10000;
    
            public bool ThrowStandardErrorExceptions = true;
    
            public cManagedProcess(string sFileName, string sArguments)
            {
                Instantiate(sFileName, sArguments);
            }
    
            public cManagedProcess(string sFileName, string sFormat, params object[] sArguments)
            {
                Instantiate(sFileName, string.Format(sFormat, sArguments));
            }
    
            private void Instantiate(string sFileName, string sArguments)
            {
                this.StartInfo = new ProcessStartInfo()
                {
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    FileName = sFileName,
                    Arguments = sArguments
                };
            }
    
            private AutoResetEvent moOutputWaitHandle;
            private AutoResetEvent moErrorWaitHandle;
    
            /// <summary>
            /// Method to start the process and wait for it to terminate
            /// </summary>
            /// <returns>Exit Code</returns>
            public int Start()
            {
                moProcess = new Process();
                moProcess.StartInfo = this.StartInfo;
                moProcess.OutputDataReceived += cManagedProcess_OutputDataReceived;
                moProcess.ErrorDataReceived += cManagedProcess_ErrorDataReceived;
    
                moOutputWaitHandle = new AutoResetEvent(false);
                moOutputStringBuilder = new StringBuilder();
    
                moErrorWaitHandle = new AutoResetEvent(false);
                moErrorStringBuilder = new StringBuilder();
    
                bool bResourceIsStarted = moProcess.Start();
    
                moProcess.BeginOutputReadLine();
                moProcess.BeginErrorReadLine();
    
                if (
                    moProcess.WaitForExit(TimeOutMilliSeconds)
                    && moOutputWaitHandle.WaitOne(TimeOutMilliSeconds)
                    && moErrorWaitHandle.WaitOne(TimeOutMilliSeconds)
                    )
                {
                    if (mbStopping)
                    {
                        return 0;
                    }
    
                    if (moProcess.ExitCode != 0 && ThrowStandardErrorExceptions)
                    {
                        throw new Exception(this.StandardError);
                    }
                    return moProcess.ExitCode;
                }
                else
                {
                    throw new TimeoutException(string.Format("Timeout exceeded waiting for {0}", moProcess.StartInfo.FileName));
                }
            }
    
            private bool mbStopping = false;
            public void Stop()
            {
                mbStopping = true;
                moProcess.Close();
            }
    
    
            private void cManagedProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
            {
                DataRecieved(e, moOutputWaitHandle, moOutputStringBuilder);
            }
    
            private void cManagedProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
            {
                DataRecieved(e, moErrorWaitHandle, moErrorStringBuilder);
            }
    
            private void DataRecieved(DataReceivedEventArgs e, AutoResetEvent oAutoResetEvent, StringBuilder oStringBuilder)
            {
                if (e.Data == null)
                {
                    oAutoResetEvent.Set();
                }
                else
                {
                    oStringBuilder.AppendLine(e.Data);
                }
            }
        }
    }
    
Sign up to request clarification or add additional context in comments.

1 Comment

This is UWP - with official API you won't be able to start process.
0

You need a javascript interpreter to run javascript.

I made good experiences with Jint: http://jint.codeplex.com/

You can make it work like in this untested snippet:

JintEngine engine = new JintEngine();

engine.Run(@"
  myFunction(p1, p2) { 
    return p1 * p2;
  }";

Console.Write(engine.Run("myFunction(4,5);");

If you want to run a js-file, just read and run it.

1 Comment

have you tried it with UWP? I am asking because I have a problem with some dependencies during install with nuget

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.