Tom McDonald
asked on
how to make a vbscript sleep w/o pinning the cpu
I am trying to make a client-side vbscript sleep but can't do it w/o pinning the cpu
The Code is below, pretty straight forward, but I get the following error:
error: object doesn't support this property or method 'Wscript.Sleep'
***********code
<html>
<head>
<SCRIPT LANGUAGE="vbscript" >
function bSleep()
document.All.whatsup.inner HTML = "I'm sleepy"
Set WScript = CreateObject("WScript.Shel l")
WScript.Sleep 2000
document.All.whatsup.inner HTML = "Done sleeping"
end function
</script>
<body onload="call bSleep()">
<div id="whatsup"></div>
</body>
</html>
***********end code
To workaround, I swap out the wscript.sleep and use a loop, but it pins the cpu and that isn't acceptable because I am sleeping so other stuff can happen in the background. Here is the loop code that pins the cpu:
***********code snip (loop1)
StartTime=Now()
Do While Now() < StartTime + 8.0 / (3600.0 * 24.0)
' loop
Loop
***********end code snip
I also tried this loop:
***********code snip (loop2)
Do While Not oBrowser.readyState = READYSTATE_COMPLETE
' sometimes this fails--failure is unacceptable
Loop
***********end code snip
FYI, You're probably wondering how the oBrowser object got involved in loop2 (above). If you want some background on the context. . . I am using this sleep code while a internetexplorer object navigates. I've found that looping structure #2 doesn't work when a site is a slow loader, i.e., it will say the readystate is complete, but it really isn't! Additionally, loop2 pins the cpu too and the spawned browser can't download anything.
Below is the complete code for my application if you want to put it all in context run this code below. For this to work you have to set your ie default tools-options-security-def ault level to 'low'
***********all code
<html>
<head>
<SCRIPT LANGUAGE="vbscript" >
function bUpdateAll()
document.All.whatsup.inner HTML = "starting"
sUrl = "http://www.aspfree.com"
const READYSTATE_COMPLETE = 4
on error resume next
Set oBrowser = CreateObject("InternetExpl orer.Appli cation")
if err.number <> 0 then
document.All.whatsup.inner HTML = "set your ie default tools-options-security-def ault level to 'low'"
exit function
end if
on error goto 0
oBrowser.Width = 600
oBrowser.Height = 400
oBrowser.Left = 50
oBrowser.Top = 50
oBrowser.Visible = true
oBrowser.Silent = true
oBrowser.Navigate(sUrl)
StartTime=Now()
Do While Not oBrowser.readyState = READYSTATE_COMPLETE
' loop
Loop
set oBrowser = nothing
document.All.whatsup.inner HTML = "done"
end function
</script>
</head>
<body onload="call bUpdateAll()">
<div id="whatsup"></div>
</body>
</html>
***********end all code
The Code is below, pretty straight forward, but I get the following error:
error: object doesn't support this property or method 'Wscript.Sleep'
***********code
<html>
<head>
<SCRIPT LANGUAGE="vbscript" >
function bSleep()
document.All.whatsup.inner
Set WScript = CreateObject("WScript.Shel
WScript.Sleep 2000
document.All.whatsup.inner
end function
</script>
<body onload="call bSleep()">
<div id="whatsup"></div>
</body>
</html>
***********end code
To workaround, I swap out the wscript.sleep and use a loop, but it pins the cpu and that isn't acceptable because I am sleeping so other stuff can happen in the background. Here is the loop code that pins the cpu:
***********code snip (loop1)
StartTime=Now()
Do While Now() < StartTime + 8.0 / (3600.0 * 24.0)
' loop
Loop
***********end code snip
I also tried this loop:
***********code snip (loop2)
Do While Not oBrowser.readyState = READYSTATE_COMPLETE
' sometimes this fails--failure is unacceptable
Loop
***********end code snip
FYI, You're probably wondering how the oBrowser object got involved in loop2 (above). If you want some background on the context. . . I am using this sleep code while a internetexplorer object navigates. I've found that looping structure #2 doesn't work when a site is a slow loader, i.e., it will say the readystate is complete, but it really isn't! Additionally, loop2 pins the cpu too and the spawned browser can't download anything.
Below is the complete code for my application if you want to put it all in context run this code below. For this to work you have to set your ie default tools-options-security-def
***********all code
<html>
<head>
<SCRIPT LANGUAGE="vbscript" >
function bUpdateAll()
document.All.whatsup.inner
sUrl = "http://www.aspfree.com"
const READYSTATE_COMPLETE = 4
on error resume next
Set oBrowser = CreateObject("InternetExpl
if err.number <> 0 then
document.All.whatsup.inner
exit function
end if
on error goto 0
oBrowser.Width = 600
oBrowser.Height = 400
oBrowser.Left = 50
oBrowser.Top = 50
oBrowser.Visible = true
oBrowser.Silent = true
oBrowser.Navigate(sUrl)
StartTime=Now()
Do While Not oBrowser.readyState = READYSTATE_COMPLETE
' loop
Loop
set oBrowser = nothing
document.All.whatsup.inner
end function
</script>
</head>
<body onload="call bUpdateAll()">
<div id="whatsup"></div>
</body>
</html>
***********end all code
You're trying a server script in client side script. Would need to be:
<%
function bSleep()
Set WScript = Server.CreateObject("WScri pt.Shell")
WScript.Sleep 2000
end function
%>
What you are trying is not possible. Client side VB will not control sevrer side sleep. Do you understand the differecne?
<%
function bSleep()
Set WScript = Server.CreateObject("WScri
WScript.Sleep 2000
end function
%>
What you are trying is not possible. Client side VB will not control sevrer side sleep. Do you understand the differecne?
What are you trying to do? if it is client side, and you can use javascricpt, you can use the setTimeout method
self.setTimeout('method()'
http://www.devguru.com/Technologies/ecmascript/quickref/win_settimeout.html
You can't do this in ASP because by its very nature, it is single-threaded, and interpreted at runtime. In other words, you can spark up a process as you've done above, wait for it, but you can't go beyond the wait. The only way to effectively do this is to build a multi-threaded COM or ActiveX object that does the processing in the background that periodically checks for the ready state transmitted from the client to the server (though I'm not sure if WScript can actually call WinAPI functions where you can call CreateThread yourself). The object in turn will transfer processing control back to your script once your ready state is achieved.
GoofyDawg
GoofyDawg
ASKER
BChan: yes, I am doing this client side. Go ahead and copy the code into a asp page and it will work.
GoofyDawg: In the '***********all code' section in my original question (above) I believe the internetexplorer.applicati on object is asynchronous, i.e., I spawn it and it runs side by side with my vbscript code.
I think, the problem stems from the fact that the vbscript code will pin the cpu when running the 'do while' loop, thus the spawned browser can't get many cpu cycles to download content. If the vbscript code could just sleep for a second and give up some cycles then the spawned browser could finish its work (note, the 'all code' will work, as is, but sometimes not when you're navigating to a really slow site it fails--which is my problem).
GoofyDawg: In the '***********all code' section in my original question (above) I believe the internetexplorer.applicati
I think, the problem stems from the fact that the vbscript code will pin the cpu when running the 'do while' loop, thus the spawned browser can't get many cpu cycles to download content. If the vbscript code could just sleep for a second and give up some cycles then the spawned browser could finish its work (note, the 'all code' will work, as is, but sometimes not when you're navigating to a really slow site it fails--which is my problem).
ASKER
Bchan, is there a way to do the settimeout in vbscript? I'd rather not convert all my code to javascript
alorentz, oh, I didn't realize that wscript wasn't available on the client side. But, if that is so, then why doesn't the script bomb when I create the wscript object?
alorentz, oh, I didn't realize that wscript wasn't available on the client side. But, if that is so, then why doesn't the script bomb when I create the wscript object?
tomandlis:
Take a look at this:
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/settimeout.asp
BChan
Take a look at this:
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/settimeout.asp
BChan
When you execute a wscript shell, it is running on the server, not the client machine. Otherwilse, I could call a script that would delete files on a client's machine and etc.
This brings me back to my first point--it is best not to build something that is going to require a wait as this is a bad situation for the server to be in.
FtB
This brings me back to my first point--it is best not to build something that is going to require a wait as this is a bad situation for the server to be in.
FtB
tomandlis,
Why not use the window.open method?
window.open("Sample.htm",n ull,
"height=200,width=400,stat us=yes,too lbar=no,me nubar=no,l ocation=no ");
What is the goal of your script?
You might be able to use this, or another approacr, such as an iframe. You then will not need to have the security settings change.
Why not use the window.open method?
window.open("Sample.htm",n
"height=200,width=400,stat
What is the goal of your script?
You might be able to use this, or another approacr, such as an iframe. You then will not need to have the security settings change.
ASKER
bchan, I believe window.open is a javascript function. Please note that this is in vbscript.
If you really want to know the purpose of this script is essentially screen scraping
1. have the client side browser go to a site
2. navigate (click) a few links on that site to get to a destination page
3. gather info from the destination page
4. submit the gathered information via http to my servers
simple huh
I do step 4 by spawning a new browser and constructing a simple form (containing the gathered information) that has its 'action' set to a receiving page on my site.
Why do this you ask? Simple, because the screen scaping can only be done from a client-side browser that accepts cookies.--The site being scrapped is password protected.
If you really want to know the purpose of this script is essentially screen scraping
1. have the client side browser go to a site
2. navigate (click) a few links on that site to get to a destination page
3. gather info from the destination page
4. submit the gathered information via http to my servers
simple huh
I do step 4 by spawning a new browser and constructing a simple form (containing the gathered information) that has its 'action' set to a receiving page on my site.
Why do this you ask? Simple, because the screen scaping can only be done from a client-side browser that accepts cookies.--The site being scrapped is password protected.
I wonder if there isn't any way to use something like this for scraping:
Function GetHTML(strURL)
Dim objXMLHTTP, strReturn
Set objXMLHTTP = Server.CreateObject("MSXML 2.ServerXM LHTTP")
objXMLHTTP.Open "GET", strURL, False
objXMLHTTP.Send
strReturn = objXMLHTTP.responseText
Set objXMLHTTP = Nothing
GetHTML = strReturn
End Function
FtB
Function GetHTML(strURL)
Dim objXMLHTTP, strReturn
Set objXMLHTTP = Server.CreateObject("MSXML
objXMLHTTP.Open "GET", strURL, False
objXMLHTTP.Send
strReturn = objXMLHTTP.responseText
Set objXMLHTTP = Nothing
GetHTML = strReturn
End Function
FtB
ASKER
fritz, yes your code will work. However, it doesn't work very well with cookies because some pages will check to see if you have a cookie (password protected site). Consequently, it is better to just click links using a internetexplorer object when scraping pwd protected sites.
Also, your script only works server side and that will put a drag on the server. Better to distribute something like this to the client.
Also, your script only works server side and that will put a drag on the server. Better to distribute something like this to the client.
ASKER
Anyway, we've gotten a little off track here. Remember, the original question is rather simple-- How can you get a client side vbscript to sleep while browsing with an internetexplorer activex object ?
So far the answers seem to be you can't unless you convert it to javascript, but I'll need an example of that (that doesn't pin the cpu) to accept that answer.
BTW, if you can remove the internetexplorer object from the equation (and still scape contents) I'll accept that too.
So far the answers seem to be you can't unless you convert it to javascript, but I'll need an example of that (that doesn't pin the cpu) to accept that answer.
BTW, if you can remove the internetexplorer object from the equation (and still scape contents) I'll accept that too.
Still going with my original answer: don't do it--program around it instead.
FtB
FtB
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>>Anyway, we've gotten a little off track here. Remember, the original question is rather simple-- How can you get a client side vbscript to sleep while browsing with an internetexplorer activex object ?
I agree - not a good idea, and will be unreliable regardless.
I agree - not a good idea, and will be unreliable regardless.
>>Set oBrowser = CreateObject("InternetExpl orer.Appli cation")<<
Oh, please don't do that--Microsoft warns against it:
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q257/7/57.ASP&NoWebContent=1
FtB
Oh, please don't do that--Microsoft warns against it:
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q257/7/57.ASP&NoWebContent=1
FtB
ASKER
bChan! You rock. I used your suggestion. Try the code below. It works and it doesn't pin the cpu.
<html>
<head>
<SCRIPT LANGUAGE="vbscript" >
dim oBrowser
function bUpdateAll()
document.all.whatsup.inner HTML = "starting"
sUrl = "http://www.aspfree.com"
const READYSTATE_COMPLETE = 4
on error resume next
Set oBrowser = CreateObject("InternetExpl orer.Appli cation")
if err.number <> 0 then
document.all.whatsup.inner HTML = "set your ie default tools-options-security-def ault level to 'low'"
exit function
end if
on error goto 0
oBrowser.Width = 600
oBrowser.Height = 400
oBrowser.Left = 50
oBrowser.Top = 50
oBrowser.Visible = true
oBrowser.Silent = true
oBrowser.Navigate(sUrl)
bSleep(1) 'Call js function that sleeps
document.All.whatsup.inner HTML = "done"
end function
function FWake(linkcase)
document.all.whatsup.inner HTML = "Im awake: " '& oBrowser.readyState
EndTime = Now() + 5.0 / (3600.0 * 24.0)
Do While Now() < EndTime and Not (oBrowser.readyState = READYSTATE_COMPLETE)
' Empty loop forces script to wait.
Loop
if linkcase = 1 then
bTemp = bClickLink("utilize")
bSleep(2)
else
document.all.whatsup.inner HTML = oBrowser.Document.body.inn erHTML
end if
end function
Function bClickLink(sHrefFrag)
bComplete = true
bClickLink = false
Dim x , i
x = oBrowser.Document.links.Le ngth
Dim s , sTheLink
For Each oLink In oBrowser.Document.links
sTemp = sTemp & "<br/>link: " & oLink.getAttribute("href")
If InStr(1, oLink.getAttribute("href") , sHrefFrag, vbTextCompare) > 0 Then
document.All.whatsup.inner HTML = "<p>clicked: " & oLink.getAttribute("href")
oLink.Click
bClickLink = True
Exit For
End If
Next
End Function
</script>
<SCRIPT LANGUAGE="javascript" >
function bSleep(theCase){
sFunc = "FWake(" + theCase + ")";
document.all.whatsup.inner HTML = "Sleeping";
window.setTimeout( sFunc, 5000);
}
</SCRIPT>
</head>
<body onload="call bUpdateAll()">
<div id="whatsup">Nothing</div>
</body>
</html>
<html>
<head>
<SCRIPT LANGUAGE="vbscript" >
dim oBrowser
function bUpdateAll()
document.all.whatsup.inner
sUrl = "http://www.aspfree.com"
const READYSTATE_COMPLETE = 4
on error resume next
Set oBrowser = CreateObject("InternetExpl
if err.number <> 0 then
document.all.whatsup.inner
exit function
end if
on error goto 0
oBrowser.Width = 600
oBrowser.Height = 400
oBrowser.Left = 50
oBrowser.Top = 50
oBrowser.Visible = true
oBrowser.Silent = true
oBrowser.Navigate(sUrl)
bSleep(1) 'Call js function that sleeps
document.All.whatsup.inner
end function
function FWake(linkcase)
document.all.whatsup.inner
EndTime = Now() + 5.0 / (3600.0 * 24.0)
Do While Now() < EndTime and Not (oBrowser.readyState = READYSTATE_COMPLETE)
' Empty loop forces script to wait.
Loop
if linkcase = 1 then
bTemp = bClickLink("utilize")
bSleep(2)
else
document.all.whatsup.inner
end if
end function
Function bClickLink(sHrefFrag)
bComplete = true
bClickLink = false
Dim x , i
x = oBrowser.Document.links.Le
Dim s , sTheLink
For Each oLink In oBrowser.Document.links
sTemp = sTemp & "<br/>link: " & oLink.getAttribute("href")
If InStr(1, oLink.getAttribute("href")
document.All.whatsup.inner
oLink.Click
bClickLink = True
Exit For
End If
Next
End Function
</script>
<SCRIPT LANGUAGE="javascript" >
function bSleep(theCase){
sFunc = "FWake(" + theCase + ")";
document.all.whatsup.inner
window.setTimeout( sFunc, 5000);
}
</SCRIPT>
</head>
<body onload="call bUpdateAll()">
<div id="whatsup">Nothing</div>
</body>
</html>
ASKER
Fritz, the article says you shouldn't do it serverside. The code above is client side.
ASKER
hmm, I think I found a way to do it all within vbscript here:
http://www.codeproject.com/asp/webtimer.asp
http://www.codeproject.com/asp/webtimer.asp
ASKER
Here is the code for the timer. I think I'm going to use this code as it is a little cleaner, but BChan you were a big help and deserve the points.
Thanks
<HTML>
<HEAD>
<title>Demonstration</titl e>
<SCRIPT LANGUAGE="VBScript">
<!--
Dim intTimerID
hr=0 'change hours
min=2 'change minutes
sec=0 'change seconds
Sub HandleTime
if hr=0 and min=0 and sec=0 then
endtime
elseif min>=0 and sec>0 then
sec=sec-1
status=hr & ":" & min & ":" & sec
intTimerID=setTimeOut("Han dleTime",9 50, "VBScript")
elseif min>0 and sec=0 then
min=min-1
sec=59
status=hr & ":" & min & ":" & sec
intTimerID=setTimeOut("Han dleTime",9 50, "VBScript")
elseif hr>=0 and min=0 then
hr=hr-1
min=59
sec=59
status=hr & ":" & min & ":" & sec
intTimerID=setTimeOut("Han dleTime",9 50, "VBScript")
end if
End Sub
Sub endtime
cleartimeout intTimerID
status = "Your Time Ended"
msgbox "Time Up"
end sub
status=hr & ":" & min & ":" & sec
intTimerID=setTimeOut("Han dleTime",9 50, "VBScript")
-->
</SCRIPT>
</HEAD>
<BODY>
<h3>You’ll see a message box when the time is up.</h3>
<hr>
<br><input type="button" value="Click before time is up" onclick="call endtime">
</BODY>
</HTML>
Thanks
<HTML>
<HEAD>
<title>Demonstration</titl
<SCRIPT LANGUAGE="VBScript">
<!--
Dim intTimerID
hr=0 'change hours
min=2 'change minutes
sec=0 'change seconds
Sub HandleTime
if hr=0 and min=0 and sec=0 then
endtime
elseif min>=0 and sec>0 then
sec=sec-1
status=hr & ":" & min & ":" & sec
intTimerID=setTimeOut("Han
elseif min>0 and sec=0 then
min=min-1
sec=59
status=hr & ":" & min & ":" & sec
intTimerID=setTimeOut("Han
elseif hr>=0 and min=0 then
hr=hr-1
min=59
sec=59
status=hr & ":" & min & ":" & sec
intTimerID=setTimeOut("Han
end if
End Sub
Sub endtime
cleartimeout intTimerID
status = "Your Time Ended"
msgbox "Time Up"
end sub
status=hr & ":" & min & ":" & sec
intTimerID=setTimeOut("Han
-->
</SCRIPT>
</HEAD>
<BODY>
<h3>You’ll see a message box when the time is up.</h3>
<hr>
<br><input type="button" value="Click before time is up" onclick="call endtime">
</BODY>
</HTML>
This has been an informative thread for my research on sleeping in ASP. Kudos to the experts for their comments.
A few comments:
Other workarounds to sleeping in ASP
http://classicasp.aspfaq.com/general/how-do-i-make-my-asp-page-pause-or-sleep.html
http://www.ehow.com/how_2001270_sleep-asp-using-ado.html
http://www7b.biglobe.ne.jp/~lunlumo/prog/sample/javascript_sleep.html
Alternative method to do web scraping with XmlHttp and still support cookies
http://www.codeproject.com/KB/library/httpautomationlibs.aspx
http://blog.netnerds.net/2006/04/asp-sustain-remote-cookie-sessions-in-an-asp-script-using-vbscript/
A few comments:
Other workarounds to sleeping in ASP
http://classicasp.aspfaq.com/general/how-do-i-make-my-asp-page-pause-or-sleep.html
http://www.ehow.com/how_2001270_sleep-asp-using-ado.html
http://www7b.biglobe.ne.jp/~lunlumo/prog/sample/javascript_sleep.html
Alternative method to do web scraping with XmlHttp and still support cookies
http://www.codeproject.com/KB/library/httpautomationlibs.aspx
http://blog.netnerds.net/2006/04/asp-sustain-remote-cookie-sessions-in-an-asp-script-using-vbscript/
FtB