[Code] Executing a cmd without the black screen (Windows)
-
@thomthom said:
Or open the file in a block so it automatically close.
Actually, the file is written within a block. So it should be closed when exiting the section in
File.open
.The code is just for illustration. It should indeed be protected for errors and possibly deletion of the temporary file.
Fredo
-
Have you tried using UI.openURL() ?
-
Using UI.openURL() I sometimes write two cmd files - the first one simply runs the second one 'minimized'.
The first cmd window flickers on and closes so fast you hardly notice it.
Then the second cmd has started minimized in the bottom bar- this is useful if you want the user to be able to abort a long process as closing the minimized cmd window will stop it...
On a MAC you simply write the one '.command' file and make that executable [chmod] and use UI.openURL()... -
@unknownuser said:
[This was a question from Dana]
On Windows, executing some external commands via the method
system(cmd)
provokes a short appearance of a black window. This depends on the kind of command you execute indeed. Note that this does not happen on Mac.One method I use is to invoke the command via the Windows Shell scripting (actually VBScript).
> #Execute a command without the black screen > def run_shell_command(cmd) > fvbs = File.join ENV["TEMP"], "temporary.vbs" > File.open fvbs, "w" do |f| > f.puts "Set WshShell = CreateObject(\"WScript.Shell\")" > f.puts "WshShell.Run \"#{cmd}\", 0" > end > system "wscript #{fvbs}" > end >
If anyone knows a more direct way to achieve it, thanks for feedback
Fredo
Fredo: Thanks for the code. I've gotten a working usage of it on a Virtual Machine but it seems to be running very slow, even slower than with the dialogs popping up. Is this expected? Could it be a bug in my code?
-
No.. I get the same long pause whenever I try to use Wsript.exe from Sketchup embedded Ruby.
Even when I set the environment var RUBYSHELL="Wscript.exe" (it's NOT set by default.)
The issue of the command shell on Windows is not unique to Sketchup embedded Ruby programming. It is a complaint by everyone running any kind of Ruby on the Windows platform.. and the Ruby Core guys do not seem to care much, so nothing gets done about it.
What is needed is a simple OS command interpreter, equivalent to cmd.exe, that does not create a shell window.
And they DO exist... the issue is are they trustworthy ??
Can they be used temporarily without replacing cmd.exe for other normal tasks.
On windows... the Env var "ComSpec" holds the path to the command interpreter.Normally Ruby looks at the Env var RUBYSHELL and uses that IF it is defined, IF NOT it uses the platform's defined command shell, and on windows that would be the pathname value of ComSpec
FYI.. access the environment vars from Ruby via the ENV hash.
ENV["RUBYSHELL"]="C:\some\path\to\othercmd.exe"
-
And to be clear.. using the env var RUBYSHELL does not work correctly on Windows because of bugs in the Ruby Core code. One bug is that a "/c" parameter is always appended to the shell command, which is wrong. It works for cmd.exe, but if another command interpreter does not use that switch, or explicitly ignore unused parameter switches, the system will return an error.
I have no idea why the Ruby Core programmer assumed that all command interpreters would accept a "/c" switch, just because cmd.exe does.
If it interests you, download the Ruby C Source and look at win32.c, line 979.
-
I'm working on a script that sends many commands to an external application (ImageMagick).
system(cmd)
is synchronous, but gives me too many black windows. However when I use this vbs script (which then executes the cmd commands), it doesn't appear to be synchronous anymore.
Is this true? If so, is there a way to make it synchronous? -
@aerilius said:
I'm working on a script that sends many commands to an external application (ImageMagick).
system(cmd)
is synchronous, but gives me too many black windows. However when I use this vbs script (which then executes the cmd commands), it doesn't appear to be synchronous anymore.
Is this true? If so, is there a way to make it synchronous?I guess you should explore the VBS command
WshShell.Run
. There are addditional parameters and maybe there is a way to make it synchronous. I must admit that I am not really familair with VBScript!Fredo
-
One neat trick Ruby does is allow any pair of character to be string delimiters instead of
"
marks.puts %/The String goes "here"/
It can really help readability.
See also %q and %Q
-
Thanks, I found it: http://msdn.microsoft.com/en-us/library/d5fk67ky%28v=vs.85%29.aspx
%(#000000)[WshShell.Run]
with an optional third argument%(#000000)[true]
waits for the program to finish.Now I use for that ruby line:
f.puts "WshShell.Run \"#{cmd.gsub(/\"/,'""')}\", 0, true"
My cmd contains lots of quotes, so I substitute%(#000000)["]
by%(#000000)[""]
. -
@ishboo said:
I've gotten a working usage of it on a Virtual Machine but it seems to be running very slow, even slower than with the dialogs popping up.
I believe I've found a work around. As I said I'm working with SketchUp -> ImageMagick and it caused the SketchUp process to be at 100% CPU for several minutes although I was only testing with SU's primitive default materials. One single image conversion from Ruby > cmd > ImageMagick took 8 seconds while it normally takes less than 0.5 seconds (so this problem was a show-stopper).
Edit: I did this same test again in Wine and paradoxically it took only 1s per image (instead of 8s).I don't think my solution is pretty, but finally I use the Windows Shell script (VBS) only to avoid the black window and to launch a batch script in another cmd shell,
%(#008000)[Set WshShell = CreateObject("WScript.Shell") WshShell.Run "batch.bat", 0]
and the batch script contains the code (not like above where the code is in WshShell.Run).@aerilius said:
WshShell.Run with an optional third argument true waits for the program to finish.
If I then don't set the third argument bWaitOnReturn =
%(#008000)[true]
, only then, the batch script will run in its own process and many times faster, but also asynchronously again.
Therefore I made a simple "file observer", that checks when the batch file is finished and then continues in the ruby code.
-
@aerilius said:
I don't think my solution is pretty, but finally I use the Windows Shell script (VBS) only to avoid the black window and to launch a batch script in another cmd shel
Could you not just make the WScript do the stuff the bat did?
-
One issue is there is what I consider a bug in the Ruby Win32 source. If you try to set
ENV["RUBYSHELL"]
to "Wscript" it will not work because the source always wants to inject a "-c
" switch into the command.
Problem is, Microsoft wrote Wscript.exe and Cscript.exe to poop out if any unknown switches are in the command. (I think cmd.exe just ignores unknown switches.)
So any way, the normal Ruby means of changing the shell that%x
and ` Kernel.`` use, will actually not work on Windows.
Advertisement