使用 VBS (Windows) 在当前 shell 打开一个可执行文件

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

我一直在搜索 2005 年之前的各种论坛,试图找出如何在当前 shell 中使用 VBS 运行 基于 shell 的应用程序。即,我打开了一个终端,并想执行这个应用程序(它进入一个 REPL)并使用我所在的终端使用它 - 相反,一个新的命令提示符正在打开,这违背了我的想法的目的此应用程序的无图形用户界面(纯)REPL 版本。此应用程序是 GNU Octave。

对于他们的 Windows 安装,他们有一个 VBS 脚本(基于 CLI arg)打开 Octave Dev 环境,或者只打开 Octave REPL(使用 --no-gui)。他们通过 VBS 脚本(见下文)执行此操作,所以我想,也许我可以修改它以让它在当前 shell 中打开 Octave REPL。事实证明这并不像我想象的那么容易......我发现我的问题的罪魁祸首是 wshShell.Run 命令,但显然只能在后台执行 运行 命令,或者作为一个新进程 - 明确地说,我想 运行 我的应用程序在当前进程中。

我想这是一个简单问题的大量序言:我如何(略微)修改以下文件以交互方式打开 Octave REPL,同时保持所有环境变量和其他设置集?


' 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

要附加到现有控制台,控制台程序必须由附加到该控制台的程序启动。

对于由 GUI 程序启动的程序

  1. 如果一个控制台程序会被赋予一个新的控制台。

  2. 如果是 GUI 程序,则不会为其提供控制台,但是它可以使用 AttachConsole API 调用来附加到任何控制台。

VBScript 无法 调用 API 个调用。

将我的评论转化为答案,尽管我仍然对您的实际需求感到有些困惑,但希望它会在下面涵盖...

就其价值而言,我的理解是 vbs 脚本基本上是实际 Octave 二进制文件的包装器,它应该安装在 Octave 根目录的 bin 文件夹中。因此,启动 repl 应该像将该目录放入您的路径并在控制台中键入 octave 一样简单。

我不知道 windows 二进制文件是否有更多差异,但在 linux 二进制文件中,您有 octave 和 octave-cli,其中后者:

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).

正如您所说,一个关键的区别是它缺少 qt 库。如果您尝试在 cli 环境中绘图,您仍然会得到图形 windows,但它们将使用 fltk 或 gnuplot 环境而不是 qt。

但除此之外,您完全可以使用支持 qt 的普通 octave 可执行文件,并在 REPL(即 --no-gui)模式下使用它,而不是完整的 gui。事实上,据我所知,至少在 linux 中,这是默认行为;您需要显式传递 --gui 选项才能启动实际的图形用户界面。也许开发人员觉得 windows 人群可能会感到困惑,因此他们扭转了这种行为并创建了 octave-guioctave 可执行文件,后者本质上是精简的 cli 版本;我不知道。如果是这种情况,我假设您可以使用 octave-gui 可执行文件并在控制台中将某种选项(大概是 --no-gui 或类似的东西)传递给 运行 它,但仍然对绘图等有完整的 qt 支持

关于将您感兴趣的一堆不相关的环境变量加载到您的会话中,没有什么可以阻止您从八度内加载这些变量(例如使用 setenv)。同样,如果您希望在启动时预定义普通的 'octave' 变量,您可以将它们放入您的 .octaverc 文件中(我猜您也可以将 setenv 声明放在那里)。我不明白如果你不加载“附加”插件,为什么你会失去绘图功能(除非你指的是我上面提到的 octaveoctave-cli 二进制文件之间的区别)。只要不是特别需要启动,那么你应该可以在八度内随时设置环境变量而不会出现问题。