MsgBox "First line"
MsgBox "Second line"
I have to click the OK button in the first message box to close it
before I see the second message box. Is there a way to get the second
message box to appear before the first one is closed? Is there some
way to spawn a separate process to run the first message box, the way
that WshShell.Run will spawn a separate process to run an external
program? I tried
strTemp = "MsgBox " & Chr(34) & "First line" & Chr(34)
Execute strTemp
MsgBox "Second line"
but it didn't make any difference. Thanks in advance to all who
respond.
Hi,
No, there is nothing in VBScript for this.
If what you want to do is displaying messages without halting the
script, here is a couple of alternatives for you (using IE as a
front end, or switch to HTA):
A)
You can roll your own display function, using an Internet Explorer
instance from your VBScript.
An example where you can dynamically put out information about what is
going on:
http://groups-beta.google.com/group/microsoft.public.scripting.vbscript/msg/75e27358e6ba0483?dmode=source
In case people has used the search bar in IE in their previous logon
session, you should turn it off before opening IE, setting the
ShowBrowserBar property before you call the SetupMSIE sub, like the
code in this post:
http://groups-beta.google.com/group/microsoft.public.scripting.wsh/msg/9f272a6e70097550?dmode=source
To have a scrolling message output window, you can use
insertAdjacentHtml and scrollIntoView.
See e.g the 3rd example by Joe Earnest in this link ("Progress Bar
with Scrolling File Names"):
http://groups-beta.google.com/group/microsoft.public.scripting.vbscript/msg/272e4296c1d80aef?dmode=source
In this link there is a modified version of the example by Joe Earnest
(progress bar is removed), where I use the window to display the
installation progress of some security updates:
http://groups.google.co.uk/group/microsoft.public.scripting.vbscript/msg/b5e097ea5b0c6c95?dmode=source
B)
HTA:
You could consider putting your script inside a HTA (HTML Application).
HTA files are HTML files hosted by mshta.exe instead of iexplore.exe,
avoiding the security restriction that iexplore.exe imposes.
HTML Applications (HTAs)
http://msdn.microsoft.com/workshop/author/hta/hta_node_entry.asp
A couple of HTA examples:
http://groups.google.co.uk/group/microsoft.public.wbem/msg/0ea183edf766c6e8?dmode=source
When running the example in the link above, fill in e.g.
Win32_OperatingSystem in the Enumerate field
http://groups-beta.google.com/group/microsoft.public.scripting.wsh/msg/71692a7a95ac2065?dmode=source
--
torgeir, Microsoft MVP Scripting and WMI, Porsgrunn Norway
Administration scripting examples and an ONLINE version of
the 1328 page Scripting Guide:
http://www.microsoft.com/technet/scriptcenter/default.mspx
Sure, it's easy. But first let's clarify some terms. First, I take it
that you are not so interested in running code asynchronously from
VBScript as you are in putting up a MsgBox/alert/popup and then having
the code continue on (in other words, an asychronous popup). Secondly,
is it more important for you to be able to see all the message boxes on
top, or is it more important that they all be shown as encountered?
The example at the bottom of this post (PopupTest.vbs and
AsyncPopup.vbs) has two variants. The one shown (with myType = 0) will
bury the first popup as IE comes up. If that's not an issue for you,
it's probably closer to what you're after. However, setting myType =
&H20000 guarantees that it's on top, but the messages are queued up and
you have to dismiss them, in turn, for the following one to come up.
But in each case you know that the popups are asynchronous because IE
appears before you dismiss the first one. Note that each *displayed*
popup will have a corresponding entry in the Alt+Tab list.
Another idea (in order to avoid having multiple files) is to use IE to
display an alert box for you. However, this has the nasty artifact
that a small additional 'stub' of IE will also be visible. Very ugly.
And setting ie.visible = false would cause the popup, too, to not be
shown. Here's a demo of it, though,
Enjoy,
Csaba Gabor from Vienna
'------------ start UglyPopup.vbs ------------
uglyPopup "Message 1"
uglyPopup "Message 2"
MsgBox "Message 3"
sub uglyPopup(msg)
Set ie = CreateObject("InternetExplorer.Application")
ie.height = 1: ie.width = 1
ie.visible = true 'false => alert not shown
ie.Navigate ("about:blank")
Do Until ie.readyState=4: WScript.Sleep(500): Loop
ie.Document.parentWindow.opener = "me" 'allows self.close
'next line should be revised to escape quotes in msg
ie.Document.parentWindow.setTimeout _
"alert('" & msg & "');self.close();", 10
End Sub
'------------- end UglyPopup.vbs -------------
OK, and now ... what you've been waiting for (put both in the same
directory and run PopupTest.vbs):
' ------------ start AsyncPopup.vbs ------------
'command line arguments are the message, timeout (seconds), title, and
' (style) bitFlags, respectively
Dim idx, ctr, vitak, oPop
Set vitak = Wscript.Arguments.Unnamed
Set oPop = CreateObject("WScript.Shell")
For Each idx in vitak: ctr = ctr+1: Next
Select Case ctr
Case 4: oPop.popup vitak(0), vitak(1), vitak(2), vitak(3)
Case 3: oPop.popup vitak(0), vitak(1), vitak(2)
Case 2: oPop.popup vitak(0), vitak(1)
Case 1: oPop.popup vitak(0)
Case Else: oPop.popup WScript.ScriptFullName & _
" must be called with 1 to 4 args" & _
vbcrlf & _
"theMessage, seconds, title, bitFlags"
End Select
' ------------- end AsyncPopup.vbs -----------
' ------------ start PopupTest.vbs ------------
AsyncPopup "Message 1", "Popup testing"
Set ie = CreateObject("InternetExplorer.Application")
ie.visible = true
ie.Navigate ("yahoo.com")
Do Until ie.readyState=4: WScript.Sleep(500): Loop
AsyncPopup "Message 2", "Popup testing"
'There must be at least one navigation before next line
ie.Navigate2 ("javascript:""<html><head><title>Demo</title></head>" & _
"<body><button type=button accesskey='c' " & _
"onClick='self.close()'><u>C</u>lose</button>" & _
"</body></html>""")
Do Until ie.readyState=4: WScript.Sleep(500): Loop
ie.Document.ParentWindow.opener="me" 'allows self.close()
AsyncPopup "Message 3", "Popup testing"
Sub AsyncPopup (msg, title)
const myType = &H0 'multiple popups
' const myType = &H20000 'always on top
CreateObject("WScript.Shell").Run _
"CScript.exe //NOLOGO " & _
popupPath & " """ & msg & _
""" 0 """ & title & """ " & (myType + 49), 0, false
End Sub
Function popupPath()
Dim i
popupPath = WScript.ScriptFullName
For i=Len(popupPath) to 1 step -1
If Mid(popupPath,i,1)="\" Then _
popupPath = Mid(popupPath,1,i) & _
"AsyncPopup.vbs": Exit Function
Next
End Function
' ------------- end PopupTest.vbs -------------
strMsgBoxFile = "\TempMsgBox.vbs"
Set objMsgBoxFile = objFileSys.CreateTextFile( strMsgBoxFile, Overwrite
)
objMsgBoxFile.WriteLine( "MsgBox " & Chr(34) & "First line" & Chr(34) )
objMsgBoxFile.Close
Set objMsgBoxFile = Nothing
objWShell.Run "cscript.exe " & strMsgBoxFile, 0
Set objMsgBoxFile = objFileSys.GetFile( strMsgBoxFile )
On Error Resume Next
objMsgBoxFile.Delete Force
On Error Goto 0
Set objMsgBoxFile = Nothing
MsgBox "Second line"
I write out a temporary .vbs file with the first MsgBox command,
execute the file with WShell.Run, and then delete it. Frankly, it's
not the most elegant code I've written, but it does what I want.
"Leslie Houk" <lh...@ghg.net> wrote in message
news:1118868895.1...@f14g2000cwb.googlegroups.com...
Maybe... I'm not really familiar with SWbemSink, but I read some of
the MSDN online documentation at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/swbemsink.asp
which states, "To make an asynchronous call, you must create an
instance of an SWbemSink object and pass it as the ObjWbemSink
parameter." However, I'm at a loss as to what the ObjWbemSink
parameter might consist of. Sorry to be a slow learner...
Leslie
Personally, it may be a little bit outta my league but if researched, it
could probably be figured out.
It's not my script so I won't post it up here but will send it to you if you
like.
Bart
"Leslie Houk" <lh...@ghg.net> wrote in message
news:1119282625.6...@z14g2000cwz.googlegroups.com...
After further research (I searched in this group for threads with
"SWbemSink" in them), I came across enough examples to let me see what
you are suggesting. I believe you are suggesting I use
"SWbemServices.ExecMethodAsync" to start the async process. However,
it seems to me that this can only be used to run external programs, as
opposed to a bit of VBScript code such as a single MsgBox command,
which is what I originally had in mind. Or am I confused about
something? (Which wouldn't suprise me a bit...)
Leslie
I find Bart's post (thanks Bart) very interesting, regardless of
whether it works out for this thread. I searched google groups for:
createobject "SWbemServices.SWbemSink" group:*.vbscript.*
As regards your code up above, the motivation in writing a separate
file (as opposed to it preexisting and calling it) is unclear to me.
Is it because you only wish to have exactly one file lying around (so
you (or the user) don't get confused about having to maintain a
correlation)? If this is the motivation, it may be possible for you to
roll the two files into one if you follow the template from an old post
of mine (April 13 post of a March 26, 2003 thread: Can .Exec be called
hidden?). The point is that you can detect the secondary call (which
you could also do based on the number of arguments) and branch based on
that.
Regards,
Csaba Gabor from Vienna
> As regards your code up above, the motivation in writing a separate
> file (as opposed to it preexisting and calling it) is unclear to me.
> Is it because you only wish to have exactly one file lying around (so
> you (or the user) don't get confused about having to maintain a
> correlation)? If this is the motivation, it may be possible for you to
> roll the two files into one if you follow the template from an old post
> of mine (April 13 post of a March 26, 2003 thread: Can .Exec be called
> hidden?). The point is that you can detect the secondary call (which
> you could also do based on the number of arguments) and branch based on
> that.
>
> Regards,
> Csaba Gabor from Vienna
Csaba,
That is an excellent idea! Rewriting my original example using
argument checking to determine the secondary call produces:
Set objArgs = WScript.Arguments
If objArgs.Count = 0 Then
objWShell.Run "cscript.exe " & WScript.ScriptFullName & "
ASYNC_ROUTINE", Hidden
MsgBox "Second line"
ElseIf objArgs.Item(0) = "ASYNC_ROUTINE" Then
MsgBox "First line"
WScript.Quit
End If
Thanks! Oh, and you are correct in thinking that I wanted to keep
everything in a single file for ease of maintenance in the future.
Leslie