Search code examples
windowsshellvbscriptoctavegnu

Opening an executable in the current shell using VBS (Windows)


I've been searching through the various forums of pre-2005 trying to find out how to run a shell-based application in the current shell using VBS. Ie, I've opened up a terminal, and want to execute this application (which enters a REPL) and use it using the terminal I'm in - instead, a new command prompt is being opened, defeating the purpose of my idea of a gui-less, (pure) REPL version of this application. This application is GNU Octave.

For their Windows installation, they have a VBS script which (based on a CLI arg) opens either the Octave Dev environment, or just the Octave REPL (using --no-gui). They do this through a VBS script (see below) and so I thought, maybe I can modify this to have it open the Octave REPL in the current shell. Turns out this isn't as easy as I thought... I've found the culprit of my issues to be the wshShell.Run command, but apparently that can only run commands in the background, or as a new process - to be clear, I want to run my application in the current process.

I guess that's a lot of preamble for a simple question: How do I (minorly) modify the below file to open the Octave REPL interactively while maintaining all of the environment variables and other settings that it sets?


' script to run octave in gui/command mode

Set wshShell = CreateObject( "WScript.Shell" )

' get the directory that script resides in
Set fso = CreateObject("Scripting.FileSystemObject")
OctavePath = fso.GetParentFolderName(WScript.ScriptFullName)

' ctavePath is now the root of the install folder, but for msys2,
' OctavePath should be OctavePath/mingw64 or OctavePath/ming32
MSysType = "MSYS"
MSysPath = OctavePath
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(OctavePath & "\mingw64\bin\octave-cli.exe") Then
  MSysPath = OctavePath & "\usr"
  MSysType = "MINGW64"
  OctavePath = OctavePath & "\mingw64" 
 ElseIf objFSO.FileExists(OctavePath & "\mingw32\bin\octave-cli.exe") Then
  MSysPath = OctavePath & "\usr"
  MSysType = "MINGW32"
  OctavePath = OctavePath & "\mingw32" 
End If

' get path as a 8.3 path
Set fo = fso.GetFolder(OctavePath)
OctavePath = fo.ShortPath
Set fo = Nothing

' set up path to ensure octave bin comes first
Set wshSystemEnv = wshShell.Environment( "PROCESS" )
if OctavePath <> MSysPath Then
  wshSystemEnv("PATH") = MSysPath  & "\bin;" & wshSystemEnv("PATH")
End If
wshSystemEnv("PATH") = OctavePath & "\bin;" & wshSystemEnv("PATH")

wshSystemEnv("MSYSTEM") = MSysType

' set terminal type
wshSystemEnv("TERM") = "cygwin"
wshSystemEnv("GNUTERM") = "wxt"

wshSystemEnv("GS") = "gs.exe"

If wshShell.ExpandEnvironmentStrings("%HOME%") = "%HOME%" Then
  Home = wshSystemEnv("USERPROFILE")
  Set fo = fso.GetFolder(Home)
  wshSystemEnv("HOME") = fo.ShortPath
  Set fo = Nothing
End If

' set Qt plugin directory and path 
If objFSO.FolderExists(OctavePath & "\qt5\bin") Then
  wshSystemEnv("PATH") = OctavePath & "\qt5\bin;" & wshSystemEnv("PATH")
  wshSystemEnv("QT_PLUGIN_PATH") = OctavePath & "\qt5\plugins"
Else
  wshSystemEnv("QT_PLUGIN_PATH") = OctavePath & "\plugins"
End If

' check args to see if told to run gui or command line
' and build other args to use
GUI_MODE=1
AllArgs = ""
Set wshArgs = WScript.Arguments
For I = 0 to wshArgs.Count - 1
  If wshArgs(I) = "--no-gui" Then GUI_MODE=0
  AllArgs = AllArgs & " " & chr(34) & wshArgs(I) & chr(34)
Next

' start octave-gui, either with console shown or hidden
If GUI_MODE = 1 then
  AllArgs = AllArgs & " " & chr(34) & "--gui" & chr(34)
  wshShell.Run chr(34) & OctavePath & "\bin\octave-gui.exe" & Chr(34) & AllArgs, 0
Else
  wshShell.Run chr(34) & OctavePath & "\bin\octave-gui.exe" & Chr(34) & AllArgs, 1
End If

' free our objects
Set fso = Nothing
Set wshShell = Nothing
Set wshSystemEnv = Nothing
Set wshArgs = Nothing

Solution

  • Converting my comments to an answer, even though I'm still a bit confused what you're actually after, but hopefully it will be covered below ...

    For what it's worth, my understanding is that the vbs script is basically a wrapper to the actual octave binary, which should be installed in the bin folder of your octave root directory. So launching the repl should be as simple as putting that directory in your path and typing octave in the console.

    I don't know if the windows binaries have more differences, but in the linux binaries, you have octave and octave-cli, where the latter:

    octave-cli has been compiled without any GUI support (Qt) which makes it smaller than the default octave executable, but also limits it to providing just the command line interface (CLI).

    A crucial difference is that it's missing qt libraries, as you say. If you try to plot within the cli environment, you'll still get graphical windows, but they'll use either the fltk or gnuplot environments instead of qt.

    But other than that, you can totally use the normal octave executable which supports qt, and use it in REPL (i.e. --no-gui) mode instead of the full gui. In fact, in linux at least, that is the default behaviour as far as I'm aware; you need to explicitly pass the --gui option to launch the actual gui. Perhaps the developers felt that the windows crowd might find that confusing, so they reversed this behaviour and created octave-gui and octave executables, with the latter essentially being the stripped-down cli version; I don't know. If that is the case, I'm assuming you can use the octave-gui executable and pass some sort of option (presumably --no-gui or something similar) to run it in the console, but still with full qt support for plots etc.

    Regarding loading a bunch of unrelated environmental variables of interest to you into your session, there's nothing stopping you from loading these from within octave (e.g. using setenv). Equally, if you want normal 'octave' variables to be predefined on startup, you can put them in your .octaverc file (you can put the setenv declarations there too, I guess). I don't understand why you'd lose plot features if you didn't load "additional" plugins (unless you're referring to the distinction between octave and octave-cli binaries I mentioned above). As long as it's not required for startup specifically, then you should be able to set environmental variables from within octave at any time without problems.