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

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

Postby fredo6 » Fri Apr 29, 2011 7:04 pm

[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 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
0
Last edited by fredo6 on Sat Apr 30, 2011 2:57 pm, edited 1 time in total.
User avatar
fredo6 
Premium Member
Premium Member
 

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

Postby thomthom » Sat Apr 30, 2011 11:33 am

Nice tip! :thumb:
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

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

Postby TIG » Sat Apr 30, 2011 11:39 am

:thumb:
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
User avatar
TIG 
Global Moderator
 

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

Postby thomthom » Sat Apr 30, 2011 11:56 am

Or open the file in a block so it automatically close.
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

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

Postby fredo6 » Sat Apr 30, 2011 12:38 pm

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
User avatar
fredo6 
Premium Member
Premium Member
 

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

Postby Jim » Sun May 01, 2011 12:56 pm

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

Jim 
Global Moderator
 

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

Postby TIG » Sun May 01, 2011 1:54 pm

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
User avatar
TIG 
Global Moderator
 

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

Postby ishboo » Tue May 24, 2011 11:12 pm

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 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?
0
SketchUp plugin marketplace: http://extendsketchup.com/

ishboo 
 

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

Postby Dan Rathbun » Tue May 24, 2011 11:39 pm

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.
    User avatar
    Dan Rathbun 
    PluginStore Author
    PluginStore Author
     

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

    Postby Dan Rathbun » Wed May 25, 2011 12:23 am

    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.
      User avatar
      Dan Rathbun 
      PluginStore Author
      PluginStore Author
       

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

      Postby Aerilius » Thu Sep 29, 2011 2:20 am

      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
      PluginStore Author
       

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

      Postby fredo6 » Thu Sep 29, 2011 8:38 pm

      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
      User avatar
      fredo6 
      Premium Member
      Premium Member
       

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

      Postby Aerilius » Thu Sep 29, 2011 9:26 pm

      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
      PluginStore Author
       

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

      Postby Jim » Thu Sep 29, 2011 9:37 pm

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

      Jim 
      Global Moderator
       

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

      Postby Aerilius » Wed Oct 05, 2011 10:31 pm

      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
      PluginStore Author
       

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

      Postby thomthom » Fri Jul 06, 2012 3:02 pm

      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
      List of my plugins and link to the CookieWare fund
      User avatar
      thomthom 
      PluginStore Author
      PluginStore Author
       

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

      Postby Dan Rathbun » Fri Jul 06, 2012 3:41 pm

      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.
        User avatar
        Dan Rathbun 
        PluginStore Author
        PluginStore Author
         

        SketchUcation One-Liner Adverts

        by Ad Machine » 5 minutes ago



        Ad Machine 
        Robot
         



         

        Return to Developers' Forum

        Who is online

        Users browsing this forum: No registered users and 13 guests