9
$\begingroup$

Is it possible to launch a front end and open a notebook from a .NETLink kernel and return a result from the notebook to .NET?

In the code below "x" appears in the .NET textbox after 10 seconds but the notebook in which its value could be changed doesn't appear.

using System;
using System.Windows.Forms;
using Wolfram.NETLink;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MathKernel kernel = new MathKernel();
            kernel.Compute("Needs[\"JLink`\"];");
            kernel.Compute("$FrontEndLaunchCommand = \"Mathematica.exe\";");
            kernel.Compute("UseFrontEnd[nb = NotebookOpen[\"exists.nb\", Visible->True];");
            kernel.Compute("Pause[10];");
            kernel.Compute("CloseFrontEnd[];");
            kernel.Compute("x");
            this.textBox1.Text = kernel.Result.ToString();
        }
    }
}

enter image description here

Alternatively, is it possible to identify the .NETLink kernel so that a notebook could sent it information via the Evaluator option?

According to MathLink - Network Programming (p. 217) it looks like it should be possible:

enter image description here

$\endgroup$
4
$\begingroup$

With a lot of help from this answer: Connect Frontend to Kernel Started by JVM via JLink

here is a demo that opens a notebook from .NET (via button1), allows the user to make a dynamic manipulation, and then sends the result back to .Net where it is displayed in the form.

enter image description here

using System;
using System.Windows.Forms;
using Wolfram.NETLink;
using System.Diagnostics;

namespace WindowsFormsApplication6
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MathKernel kernel = new MathKernel();
            kernel.Compute("linkName = \"Bob\"");
            kernel.Compute("remoteLinkObj = LinkOpen[linkName, LinkMode -> Listen]");

            kernel.Compute("Needs[\"JLink`\"]");
            kernel.Compute("$FrontEndLaunchCommand = \"C:\\Program Files\\Wolfram Research\\Mathematica\\7.0\\Mathematica.exe\"");
            kernel.Compute("UseFrontEnd[nb = CreateDocument[Null, Visible -> False]; NotebookWrite[nb, Cell[BoxData[{RowBox[{RowBox[{\"linkName\", \"=\", \"\\\"Bob\\\"\"}], \";\"}], \" \", RowBox[{RowBox[{\"feLinkObject\", \"=\", RowBox[{\"LinkOpen\", \"[\", RowBox[{\"linkName\", \",\", RowBox[{\"LinkMode\", \"\\[Rule]\", \"Connect\"}]}], \"]\"}]}], \";\"}], \" \", RowBox[{RowBox[{\"SetAttributes\", \"[\", RowBox[{\"remoteEval\", \",\", \"HoldRest\"}], \"]\"}], \";\"}], \" \", RowBox[{RowBox[{RowBox[{\"remoteEval\", \"[\", RowBox[{\"link_LinkObject\", \",\", \"expr_\"}], \"]\"}], \":=\", RowBox[{\"(\", RowBox[{RowBox[{\"LinkWrite\", \"[\", RowBox[{\"link\", \",\", RowBox[{\"Unevaluated\", \"[\", \"expr\", \"]\"}]}], \"]\"}], \";\", RowBox[{\"LinkRead\", \"[\", \"link\", \"]\"}]}], \")\"}]}], \";\"}]}], \"Input\"]]; SelectionMove[nb, Previous, Cell]; SelectionEvaluate[nb];  NotebookClose[nb]]");

            Process.Start(@"C:\Users\chrisd\Documents\front end side.nb");

            kernel.Compute("evalLoop[link_LinkObject] := Module[{resultOfEval, exprIn, exprOut, evalMessages}, evalMessages = {}; collectMessages[m_] := AppendTo[evalMessages, m]; Internal`AddHandler[\"Message\", collectMessages]; While[True, evalMessages = {}; exprIn = LinkRead[link, Hold]; resultOfEval = Check[exprOut = ReleaseHold[exprIn], $Failed]; Which[resultOfEval === $Failed, LinkWrite[link, EvalError[\"In\" -> exprIn, \"Out\" -> exprOut, \"Messages\" -> evalMessages]], True, LinkWrite[link, exprOut]]]; Internal`RemoveHandler[\"Message\", collectMessages]; LinkWrite[link, \"Evaluation loop is off\"]]");
            kernel.Compute("evalLoop[remoteLinkObj]");
            kernel.Compute("x");
            this.textBox1.Text = kernel.Result.ToString();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.