简体   繁体   English

是否可以从ruby GUI脚本(.rbw)启动控制台进程

[英]Is it possible to start console process from ruby GUI script (.rbw)

I have a GUI Ruby tool that needs to spawn a child command-line process, for example ping. 我有一个GUI Ruby工具,需要生成一个子命令行过程,例如ping。 If i do this on Windows, the console window will appear and dissapear for console process, that is very annoying. 如果我在Windows上执行此操作,控制台窗口将出现,并且在控制台过程中消失,这非常烦人。 Is it possible to start a process from GUI Ruby script with no console window visible? 是否可以从没有控制台窗口的GUI Ruby脚本启动进程? If i use backtick operator or Kernel#system , the console window will appear, see example below: 如果我使用反引号运算符或Kernel#system ,则将显示控制台窗口,请参见以下示例:

require 'Tk'
require 'thread'
Thread.new { `ping 8.8.8.8` }
TkRoot.new.mainloop

在此处输入图片说明

The issue is that every executable on Windows is defined to be either a GUI executable or a Console executable (well, there's more detail than that but it doesn't matter here) at the time it is built. 问题在于,Windows上的每个可执行文件在生成时都被定义为GUI可执行文件或Console可执行文件(当然,这里有更多详细信息,但这并不重要)。 The executable that's running your Ruby script is a GUI executable (it also happens to use Tk to actually build a GUI, even if only a very simple one in your screenshot) and the ping executable is a Console executable. 运行Ruby脚本的可执行文件是GUI可执行文件(即使您的屏幕快照中只有一个非常简单的脚本,它也恰好使用Tk来实际构建GUI),而ping可执行文件是Console可执行文件。 If a GUI executable starts a Console executable, a console is automatically created to run the executable in; 如果GUI可执行文件启动控制台可执行文件,则会自动创建一个控制台以在其中运行该可执行文件。 you can't change this . 不能改变这个

Of course, the picture is more complex than that. 当然,情况要复杂得多。 That's because a console application can actually work with the GUI (it just needs to do the right API calls) and you can use a whole catalogue of tricks to cause the console window to stay out of the way (such as starting ping through an appropriately-configured shortcut file) but such things are rather awkward. 那是因为控制台应用程序实际上可以与GUI一起使用(它只需要执行正确的API调用),并且您可以使用整个技巧目录来使控制台窗口不受影响(例如,通过适当的方式开始ping操作) -配置的快捷方式文件),但此类操作相当尴尬。 The easiest way is to have the console window be there the whole time by making Ruby itself be a console app (through naming your script with the .rb suffix, not .rbw ). 最简单的方法是通过使Ruby本身成为控制台应用程序(通过使用.rb后缀而不是.rbw命名脚本 )来使控制台窗口始终存在。 Yes, it doesn't really get rid of the problem, but it stops any annoying flashing. 是的,它并不能真正解决问题,但是可以消除任何令人讨厌的闪烁。

If you were using ping as the purpose of your app (ie, to find out if services were up) then I'd as whether it is possible/advisable to switch to writing the checking code directly in Ruby by connecting to the service instead of pinging it, as ping just measures whether the target OS kernel is alive, and not the service executable. 如果您使用ping作为应用程序的目的(例如,确定服务是否启动),那么我想是否有可能/建议通过连接到服务而不是直接在Ruby中编写检查代码来代替ping它,因为ping只是测量目标OS内核是否处于活动状态,而不是服务可执行文件。 This is a fine distinction, but I've seen machines get into a state where no executables were running but the machine was still responding to pings; 这是一个很好的区别,但是我已经看到机器进入一种状态,其中没有可执行文件在运行,但是机器仍在响应ping。 this was very strange and can totally break your mental abstractions but can happen. 这是非常奇怪的,可以完全破坏您的心理抽象,但是可能发生。 But since you're only using ping as an example, I think you can just focus on the (rather problematic) console handling. 但是由于您仅以ping为例,所以我认为您可以只关注(而不是有问题的)控制台处理。 Still, if you can do it without running a subprocess then definitely choose that method (on Windows; if you were on any sort of Unix you wouldn't have this problem at all). 不过,如果您可以在不运行子进程的情况下做到这一点,那么绝对可以选择该方法(在Windows上;如果您使用的是任何类型的Unix,则根本不会出现此问题)。

It is indeed possible to spawn processes with Ruby. 确实有可能使用Ruby生成进程。 Here is a couple of ways to do it . 这是几种方法 I am not sure what you mean with 我不确定你的意思

the console window will appear and dissapear for console process 控制台窗口将出现,并在控制台过程中消失

but I think the best way for you to do it is to simply grab out and err and show it to your user in your own window. 但是我认为您最好的方法就是简单地抓住并犯错,然后在自己的窗口中显示给用户。 If you want the native windows console to appear wou probably need to something fancy with windows scripting. 如果要显示本机Windows控制台,则可能需要使用Windows脚本编写一些内容。

One way to keep a spawned console alive is to have it run a batch file with a PAUSE command at the end: 使衍生的控制台保持活动的一种方法是让它在末尾运行带有PAUSE命令的批处理文件:

rungping.bat: rungping.bat:

ping %1
pause
exit

In your ruby file: 在您的ruby文件中:

Thread.new {`start runping.bat 8.8.8.8`}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM