• Login
sketchucation logo sketchucation
  • Login
ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

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

Scheduled Pinned Locked Moved Developers' Forum
17 Posts 7 Posters 6.6k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    fredo6
    last edited by fredo6 29 Apr 2011, 18:04

    [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

    1 Reply Last reply Reply Quote 0
    • T Offline
      thomthom
      last edited by 30 Apr 2011, 10:33

      Nice tip! πŸ‘

      Thomas Thomassen β€” SketchUp Monkey & Coding addict
      List of my plugins and link to the CookieWare fund

      1 Reply Last reply Reply Quote 0
      • T Offline
        TIG Moderator
        last edited by 30 Apr 2011, 10:39

        πŸ‘
        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' πŸ˜•

        TIG

        1 Reply Last reply Reply Quote 0
        • T Offline
          thomthom
          last edited by 30 Apr 2011, 10:56

          Or open the file in a block so it automatically close.

          Thomas Thomassen β€” SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund

          1 Reply Last reply Reply Quote 0
          • F Offline
            fredo6
            last edited by 30 Apr 2011, 11:38

            @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

            1 Reply Last reply Reply Quote 0
            • J Offline
              Jim
              last edited by 1 May 2011, 11:56

              Have you tried using UI.openURL() ?

              Hi

              1 Reply Last reply Reply Quote 0
              • T Offline
                TIG Moderator
                last edited by 1 May 2011, 12:54

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

                TIG

                1 Reply Last reply Reply Quote 0
                • I Offline
                  ishboo
                  last edited by 24 May 2011, 22:12

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

                  SketchUp plugin marketplace: http://extendsketchup.com/

                  1 Reply Last reply Reply Quote 0
                  • Dan RathbunD Offline
                    Dan Rathbun
                    last edited by 24 May 2011, 22:39

                    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"

                    I'm not here much anymore.

                    1 Reply Last reply Reply Quote 0
                    • Dan RathbunD Offline
                      Dan Rathbun
                      last edited by 24 May 2011, 23:23

                      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 not here much anymore.

                      1 Reply Last reply Reply Quote 0
                      • A Offline
                        Aerilius
                        last edited by 29 Sept 2011, 01:20

                        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?

                        1 Reply Last reply Reply Quote 0
                        • F Offline
                          fredo6
                          last edited by 29 Sept 2011, 19:38

                          @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

                          1 Reply Last reply Reply Quote 0
                          • J Offline
                            Jim
                            last edited by 29 Sept 2011, 20:37

                            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

                            Hi

                            1 Reply Last reply Reply Quote 0
                            • A Offline
                              Aerilius
                              last edited by 29 Sept 2011, 20:47

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

                              1 Reply Last reply Reply Quote 0
                              • A Offline
                                Aerilius
                                last edited by 5 Oct 2011, 21:31

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


                                run_shell_command.rb

                                1 Reply Last reply Reply Quote 0
                                • T Offline
                                  thomthom
                                  last edited by 6 Jul 2012, 14:02

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

                                  Thomas Thomassen β€” SketchUp Monkey & Coding addict
                                  List of my plugins and link to the CookieWare fund

                                  1 Reply Last reply Reply Quote 0
                                  • Dan RathbunD Offline
                                    Dan Rathbun
                                    last edited by 6 Jul 2012, 14:41

                                    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.

                                    I'm not here much anymore.

                                    1 Reply Last reply Reply Quote 0
                                    • 1 / 1
                                    • First post
                                      Last post
                                    Buy SketchPlus
                                    Buy SUbD
                                    Buy WrapR
                                    Buy eBook
                                    Buy Modelur
                                    Buy Vertex Tools
                                    Buy SketchCuisine
                                    Buy FormFonts

                                    Advertisement