sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

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

    Scheduled Pinned Locked Moved Developers' Forum
    17 Posts 7 Posters 6.6k Views 7 Watching
    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.
    • fredo6F Offline
      fredo6
      last edited by fredo6

      [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
      • thomthomT Offline
        thomthom
        last edited by

        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
        • TIGT Offline
          TIG Moderator
          last edited by

          πŸ‘
          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
          • thomthomT Offline
            thomthom
            last edited by

            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
            • fredo6F Offline
              fredo6
              last edited by

              @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

                Have you tried using UI.openURL() ?

                Hi

                1 Reply Last reply Reply Quote 0
                • TIGT Offline
                  TIG Moderator
                  last edited by

                  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

                    @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

                      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

                        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

                          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
                          • fredo6F Offline
                            fredo6
                            last edited by

                            @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

                              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

                                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

                                  @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
                                  • thomthomT Offline
                                    thomthom
                                    last edited by

                                    @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

                                      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