none
How do I minimize a window in VBScript with WMI

    Question

  • I found this script to open a program in a hidden window and it worked great.  I tried changing the constant from 0 to 2, 6, 7, and 11 to see if I could get it to run in a minimized window but none of the other settings worked.  The program opens but the window does not minimize.

    Const MINIMIZE_WINDOW = 6

    strComputer = "."

    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

    Set objStartup = objWMIService.Get("Win32_ProcessStartup")

    Set objConfig = objStartup.SpawnInstance_

    objConfig.ShowWindow = MINIMIZE_WINDOW

    Set objProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")

    strCommand = """C:\Program Files\Windows Media Player\wmplayer.exe"" /play http://listen.emfcdn.com/.../001_high.asx"

    objProcess.Create strCommand, null, objConfig, intProcessID

    Can you help?

    Thanks!

    Thursday, July 11, 2013 1:27 PM

Answers

  • Yes, after some more research and experimenting I have not been able to find a WMI solution.  It's strange that the WMI code I originally tried will work to hide the window completely with the 0 constant but does not seem to use any of the other constants that would minimize the window.

    So the only thing I've found so far that works consistently is to use the "not recommended" SendKeys solution.

    I found after using a variety of SendKeys approaches that all use the WScript.Sleep command to wait a magical amount of time (100, 200, 500...) that none of those approaches worked consistently.

    I came up with an approach that doesn't use WScript.Sleep and has been working consistently.

    Dim objShell, strCommand, objWMP
    
    'Create the shell object
    Set objShell = Wscript.CreateObject("Wscript.Shell")
    
    'Set the command to open the application
    strCommand = """C:\Program Files\Windows Media Player\wmplayer.exe"" /play http://listen.emfcdn.com/play/sk/001_high.asx"
    
    'Execute the command
    Set objWMP = objShell.Exec(strCommand)
    
    'Wait until the application is active (may be more reliable than WScript.Sleep)
    Do While objShell.AppActivate("Windows Media Player") = False
       objShell.AppActivate objWMP.ProcessID
    Loop
    
    'Use the Alt+Spacebar+n combination to minimize the window
    objShell.SendKeys "% n"
    
    'Clean up and exit
    Set objWMP = Nothing
    Set objShell = Nothing
    WScript.Quit

    • Marked as answer by DPLeo Tuesday, July 16, 2013 12:55 PM
    Tuesday, July 16, 2013 12:55 PM

All replies

  • Since you're doing this on the local computer, you could just use WshShell.Run for this purpose.  It also accepts a WindowStyle argument (with the same values;  0 = Hidden, 7 = Minimized, etc).

    Set WshShell = CreateObject("WScript.Shell")
    
    strCommand = """C:\Program Files\Windows Media Player\wmplayer.exe"" /play http://listen.emfcdn.com/.../001_high.asx"
    
    WshShell.Run strCommand, 7, False
    
    ' Run method details:
    ' http://msdn.microsoft.com/en-us/library/d5fk67ky(v=vs.84).aspx

    • Proposed as answer by Bill_StewartModerator Thursday, July 11, 2013 2:24 PM
    • Unproposed as answer by DPLeo Thursday, July 11, 2013 2:36 PM
    • Proposed as answer by Bill_StewartModerator Thursday, July 11, 2013 4:58 PM
    • Unproposed as answer by DPLeo Thursday, July 11, 2013 10:05 PM
    Thursday, July 11, 2013 1:45 PM
  • Thanks for the reply.  I should have mentioned I tried WhsShell.Run, strCommand, 7, False but as the MSDN documentation says "Note that not all programs make use of this information."

    http://msdn.microsoft.com/en-us/library/d5fk67ky(v=vs.84).aspx

    I also tried AppActivate and SendKeys "% n" with a variety of configurations and iterations with no success.  The closest I've been so far is to use the script I posted above with a 0 const to hide the window completely.  But I would like to minimize if possible and am hoping someone has a deeper understanding of WMI than I do and knows how it can be done.
    Thursday, July 11, 2013 2:31 PM
  • Hi,

    If the program you're running ignores the program startup window state, then you can't (at least, not easily) start it minimized. Also, SendKeys is fraught with problems and is not recommended.

    Bill

    Thursday, July 11, 2013 2:38 PM
  • "If the program you're running ignores the program startup window state ..."

    It doesn't seem to be ignoring all the startup window states because as I mentioned the 0 is working to hide the window but the other constants to minimize the window do not work.

    "... you can't (at least, not easily) start it minimized. ..."

    Yes, the "not easily" part is what I'm looking for. :)

    "... SendKeys is fraught with problems and is not recommended. ..."

    Agreed, which is why I'm looking for another solution.

    Thanks!

    Thursday, July 11, 2013 3:16 PM
  • Hi,

    "Not easily" means that you can't really do what you want using basic scripting. You've crossed over into Win32 window management APIs at that point, and you can't do these things from a script.

    Bill

    • Proposed as answer by jrv Thursday, July 11, 2013 5:46 PM
    • Unproposed as answer by DPLeo Thursday, July 11, 2013 10:05 PM
    Thursday, July 11, 2013 3:32 PM
  • Hi,

    The answer to this question seems to be "you cannot do what you want from a script."

    Bill

    Monday, July 15, 2013 4:35 PM
  • Yes, after some more research and experimenting I have not been able to find a WMI solution.  It's strange that the WMI code I originally tried will work to hide the window completely with the 0 constant but does not seem to use any of the other constants that would minimize the window.

    So the only thing I've found so far that works consistently is to use the "not recommended" SendKeys solution.

    I found after using a variety of SendKeys approaches that all use the WScript.Sleep command to wait a magical amount of time (100, 200, 500...) that none of those approaches worked consistently.

    I came up with an approach that doesn't use WScript.Sleep and has been working consistently.

    Dim objShell, strCommand, objWMP
    
    'Create the shell object
    Set objShell = Wscript.CreateObject("Wscript.Shell")
    
    'Set the command to open the application
    strCommand = """C:\Program Files\Windows Media Player\wmplayer.exe"" /play http://listen.emfcdn.com/play/sk/001_high.asx"
    
    'Execute the command
    Set objWMP = objShell.Exec(strCommand)
    
    'Wait until the application is active (may be more reliable than WScript.Sleep)
    Do While objShell.AppActivate("Windows Media Player") = False
       objShell.AppActivate objWMP.ProcessID
    Loop
    
    'Use the Alt+Spacebar+n combination to minimize the window
    objShell.SendKeys "% n"
    
    'Clean up and exit
    Set objWMP = Nothing
    Set objShell = Nothing
    WScript.Quit

    • Marked as answer by DPLeo Tuesday, July 16, 2013 12:55 PM
    Tuesday, July 16, 2013 12:55 PM
  • I came up with an approach that doesn't use WScript.Sleep and has been working consistently.

    Scripts that use the SendKeys method may work for most of the time but sooner or later they will fail in a multi-tasking environment because you cannot possibly predict each and every pop-up warning or dialog box that will steal the current focus.
    Tuesday, July 16, 2013 1:40 PM
  • A SendKeys solution is fraught with problems as noted. Using this technique is usually a last resort and in general will not work consistently depending on what's running on the computer. In general, SendKeys is discouraged, particularly for production applications.

    Bill

    Tuesday, July 16, 2013 2:12 PM

  • ... Scripts that use the SendKeys method may work for most of the time but sooner or later they will fail in a multi-tasking environment because you cannot possibly predict each and every pop-up warning or dialog box that will steal the current focus.

    Yes, that has been my experience also but I think it had more to do with WScript.Sleep than SendKeys.  All the approaches I found online used WScript.Sleep, which of course will lead right into the problem you describe with focus unpredictability.  With those approaches I was having the problem you described and the script worked less than most of the time.  WScript.Sleep was very unreliable.

    So far, I have not experienced this problem with my approach, which avoids WScript.Sleep.

    I'd still prefer a WMI solution but am happy that I have something that is working consistently now.

    Tuesday, July 16, 2013 7:57 PM
  • It's been ages since I used this, but AutoIt is a pretty good product for when you absolutely need to interact with the GUI from a script.  It can send input straight to the window controls (instead of simulating keyboard input, which means it doesn't matter what window has focus most of the time), it can temporary lock out the keyboard / mouse hardware so the user doesn't interfere, etc.

    http://www.autoitscript.com/site/autoit/

    Tuesday, July 16, 2013 8:09 PM
  • WScript.Sleep was very unreliable.

    I have never ever heard of the sleep function being unreliable. It pauses for exactly the number of milliseconds you specify. What makes you think that it cannot be relied upon? What tests have you performed that can be repeated by others?

    Or did you perhaps mean that scripts which use the sleep function cannot be relied upon because it is impossible predict how long one should put the script to sleep? This would indicate an inappropriate use of the sleep function.

    Tuesday, July 16, 2013 8:13 PM
  • ... scripts which use the sleep function cannot be relied upon because it is impossible predict how long one should put the script to sleep? This would indicate an inappropriate use of the sleep function.

    Yes, this is the context that I found WScript.Sleep to be very unreliable.  As you indicated in your earlier post, "in a multi-tasking environment because you cannot possibly predict each and every pop-up warning or dialog box that will steal the current focus." makes using WScript.Sleep with SendKeys very unreliable.

    Unfortunately, all of the examples I found online for SendKeys include the use of WScript.Sleep.  My approach does not use WScript.Sleep and, so far, has been very consistent.

    I will always prefer a WMI solution over SendKeys but in this case there doesn't seem to be a WMI solution.

    Wednesday, July 17, 2013 12:37 PM