Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute JavaScript function with C# in UWP without WebView

Tags:

javascript

c#

uwp

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?

like image 400
RTDev Avatar asked Mar 20 '26 20:03

RTDev


1 Answers

  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);
                }
            }
        }
    }
    
like image 78
Nick Allan Avatar answered Mar 23 '26 10:03

Nick Allan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!