3
$\begingroup$

There are two duplicate's of this question that seem to only work on linux/osx currently.

So how can I viably run mathematica scripts without spawning a new session each time from command prompt?

I would like to support stdout.

$\endgroup$
6
  • 3
    $\begingroup$ Please to not use the bugs tag initially, even if it clearly seems to be the case; by community convention it is applied later. Also, links to the duplicates would seem highly appropriate. $\endgroup$
    – Mr.Wizard
    Aug 5, 2015 at 5:01
  • $\begingroup$ I'm also interesting for this question on Windows $\endgroup$
    – Bendesarts
    Aug 5, 2015 at 7:08
  • 1
    $\begingroup$ Can I ask why you don't want to initialize the kernel each time? Are the scripts particularly fast running? The overhead in restarting the kernel may be relatively trivial and does guarantee that the kernel is clean (as its going to be) at the start of each run. $\endgroup$
    – Ymareth
    Aug 5, 2015 at 8:01
  • $\begingroup$ @Ymareth Yes they are fast running. 6 secs vs 1 sec are a big difference. This question is related. $\endgroup$
    – William
    Aug 5, 2015 at 20:55
  • $\begingroup$ @Bendesarts the current answer works with some caveats. $\endgroup$
    – William
    Aug 22, 2015 at 1:21

1 Answer 1

6
$\begingroup$

This works for running scripts. Print is not supported although the last return value defaults to the stdout.

Needs["NETLink`"];
InstallNET[];

ShowNETConsole["stdout"];
LoadNETType["System.Console"];
Console`Out@WriteLine["Hello from .NET"];

WatchFile[file_String, fun_] := 
  Module[{time, time2, w, e}, 
   w = NETNew["System.IO.FileSystemWatcher"];
   LoadNETType["System.IO.NotifyFilters"];
   LoadNETType["System.IO.File"];
   w@Path = FileNameJoin@Drop[FileNameSplit[file], -1];
   w@NotifyFilter = NotifyFilters`LastWrite;
   w@Filter = Last@FileNameSplit[file];
   e = AddEventHandler[w@Changed, myHandler];
   time = 0;
   myHandler[source_, 
     e_] := (time2 = File`GetLastWriteTime[file]@ToBinary[];
     If[time == time2, Null;, fun[source, e];];
     time = time2;);
   w@EnableRaisingEvents = True;
   Return[{w, e}];];
WatchFile["C:\\Users\\a\\Desktop\\in.txt", Function[{w, e},
  Export[FileNameJoin@
     Insert[Drop[FileNameSplit@e@FullPath, -1], "out.txt", -1], 
    ToExpression@Import[e@FullPath]];
  ]]

and the c# script.

using System;

public class Watcher
{
    public static int exit=1;
    static DateTime lastRead = DateTime.MinValue;
    public static void Main(string[] args)
    {
        System.IO.File.WriteAllText(@"C:\Users\a\Desktop\in.txt", String.Join(" ", args));
        System.IO.FileSystemWatcher watcher = new System.IO.FileSystemWatcher();
        watcher.Path = "C:\\Users\\a\\Desktop";
        watcher.NotifyFilter = System.IO.NotifyFilters.LastWrite;
        watcher.Filter = "out.txt";
        watcher.Changed += new System.IO.FileSystemEventHandler(OnChanged);
        watcher.EnableRaisingEvents = true;
        while (exit != 0) ;
    }
    private static void OnChanged(object source, System.IO.FileSystemEventArgs e)
    {
        DateTime lastWriteTime = System.IO.File.GetLastWriteTime(e.FullPath);
        if (lastWriteTime != lastRead)
        {
            Console.Write(
              System.IO.File.ReadAllText(e.FullPath)
            );
            exit = 0;
            lastRead = lastWriteTime;
        }
    }
}

compile script.

C:\Windows\Microsoft.Net\Framework\v4.0.30319\csc.exe test.cs
$\endgroup$

Your Answer

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

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