2
$\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$
  • 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 '15 at 5:01
  • $\begingroup$ I'm also interesting for this question on Windows $\endgroup$ – Bendesarts Aug 5 '15 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 '15 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 '15 at 20:55
  • $\begingroup$ @Bendesarts the current answer works with some caveats. $\endgroup$ – William Aug 22 '15 at 1:21
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, privacy policy and cookie policy

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