## [Code] Executing a cmd without the black screen (Windows)

### [Code] Executing a cmd without the black screen (Windows)

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

Code: Select all
#Execute a command without the black screendef 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
0
Last edited by fredo6 on Sat Apr 30, 2011 2:57 pm, edited 1 time in total.

fredo6
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

Nice tip!
0
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

It might be an idea to use File.close() and then File.delete() on 'fvbs' at the end of the method...
Otherwise the executable file hangs around in the temp-folder, and it might not be 're-writable' in the same session if it's not been 'closed'
0
TIG

TIG
Global Moderator

### Re: [Code] Executing a cmd without the black screen (Windows

Or open the file in a block so it automatically close.
0
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

thomthom wrote: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
0

fredo6
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

Have you tried using UI.openURL() ?
0
Hi

Jim
Global Moderator

### Re: [Code] Executing a cmd without the black screen (Windows

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()...
0
TIG

TIG
Global Moderator

### Re: [Code] Executing a cmd without the black screen (Windows

Fredo6 wrote:[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).

Code: Select all
#Execute a command without the black screendef 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?
0
SketchUp plugin marketplace: http://extendsketchup.com/

ishboo

### Re: [Code] Executing a cmd without the black screen (Windows

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"
0
I'm not here much anymore. But a PM will fire email notifications.

Dan Rathbun
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

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.
0
I'm not here much anymore. But a PM will fire email notifications.

Dan Rathbun
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

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?
0

Aerilius
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

Aerilius wrote: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
0

fredo6
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

Thanks, I found it: http://msdn.microsoft.com/en-us/library ... 85%29.aspx
WshShell.Run with an optional third argument 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 " by "".
0
Last edited by Aerilius on Thu Sep 29, 2011 9:47 pm, edited 1 time in total.

Aerilius
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

One neat trick Ruby does is allow any pair of character to be string delimiters instead of " marks.

puts %/The String goes "here"/

0
Hi

Jim
Global Moderator

### Re: [Code] Executing a cmd without the black screen (Windows

ishboo wrote: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,
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 wrote:WshShell.Run with an optional third argument true waits for the program to finish.

If I then don't set the third argument bWaitOnReturn = 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.
0

Aerilius
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

Aerilius wrote: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?
0
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
PluginStore Author

### Re: [Code] Executing a cmd without the black screen (Windows

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.
0
I'm not here much anymore. But a PM will fire email notifications.

Dan Rathbun
PluginStore Author