Solved

how to make a vbscript sleep w/o pinning the cpu

Posted on 2004-08-19
22
75,457 Views
Last Modified: 2012-05-05
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.innerHTML = "I'm sleepy"
            Set WScript = CreateObject("WScript.Shell")
            WScript.Sleep 2000
            document.All.whatsup.innerHTML = "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-default level to 'low'

***********all code

<html>
<head>
<SCRIPT LANGUAGE="vbscript" >
      function bUpdateAll()
            document.All.whatsup.innerHTML = "starting"
            sUrl = "http://www.aspfree.com"

            const READYSTATE_COMPLETE = 4
            on error resume next

            Set oBrowser = CreateObject("InternetExplorer.Application")

            if err.number <> 0 then            
                  document.All.whatsup.innerHTML = "set your ie default tools-options-security-default 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.innerHTML = "done"
      end function
</script>
</head>
<body onload="call bUpdateAll()">
      <div id="whatsup"></div>
</body>
</html>

***********end all code
0
Comment
Question by:tomandlis
  • 9
  • 5
  • 4
  • +3
22 Comments
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11842000
In general, you don't want to do this. It is much better to arrange your code in such a way this isn't necessary.

FtB
0
 
LVL 31

Expert Comment

by:alorentz
ID: 11842058
You're trying a server script in client side script.  Would need to be:

<%
     function bSleep()
          Set WScript = Server.CreateObject("WScript.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?
0
 
LVL 4

Expert Comment

by:BChan
ID: 11842375

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()', 5000)  //-- Call method() in 5000 miliseconds

http://www.devguru.com/Technologies/ecmascript/quickref/win_settimeout.html
0
 
LVL 12

Expert Comment

by:GoofyDawg
ID: 11842655
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
0
 

Author Comment

by:tomandlis
ID: 11842873
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.application 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).
0
 

Author Comment

by:tomandlis
ID: 11842912
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?
0
 
LVL 4

Expert Comment

by:BChan
ID: 11842951
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11842964
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
0
 
LVL 4

Expert Comment

by:BChan
ID: 11843147
tomandlis,
Why not use the window.open method?
window.open("Sample.htm",null,
    "height=200,width=400,status=yes,toolbar=no,menubar=no,location=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.
0
 

Author Comment

by:tomandlis
ID: 11843425
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.
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11843707
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("MSXML2.ServerXMLHTTP")
      objXMLHTTP.Open "GET", strURL, False
      objXMLHTTP.Send
      strReturn = objXMLHTTP.responseText
      Set objXMLHTTP = Nothing
      GetHTML = strReturn
End Function

FtB
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:tomandlis
ID: 11843761
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.
0
 

Author Comment

by:tomandlis
ID: 11843832
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.
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11843858
Still going with my original answer: don't do it--program around it instead.

FtB
0
 
LVL 4

Accepted Solution

by:
BChan earned 500 total points
ID: 11844368
You can call javascript function from a vb:

<html>
<head>
<SCRIPT LANGUAGE="vbscript" >
     function bUpdateAll()
          document.all.whatsup.innerHTML = "starting"
          sUrl = "http://www.aspfree.com"

          const READYSTATE_COMPLETE = 4
          on error resume next

          Set oBrowser = CreateObject("InternetExplorer.Application")

          if err.number <> 0 then          
               document.all.whatsup.innerHTML = "set your ie default tools-options-security-default 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() 'Call js function that sleeps
         ' StartTime=Now()
         ' Do While Not oBrowser.readyState = READYSTATE_COMPLETE
               '     loop
         ' Loop
          set oBrowser = nothing
          document.All.whatsup.innerHTML = "done"
     end function
</script>
</head>
<body onload="call bUpdateAll()">
     <div id="whatsup"></div>
</body>
</html>




<SCRIPT LANGUAGE="vbscript" >
   
     function FWake()
          document.all.whatsup.innerHTML = "Im awake"            

     end function
</script>
<SCRIPT LANGUAGE="javascript" >
 function bSleep(){

          document.all.whatsup.innerHTML = "Sleeping"            
            window.setTimeout( "FwAKE()", 5000); <!-- change 5000 to your wait time-->
                     

      }
</SCRIPT  >
<Div ID=whatsussp>NOTHING</Div >

0
 
LVL 31

Expert Comment

by:alorentz
ID: 11844437
>>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.
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 11844805
>>Set oBrowser = CreateObject("InternetExplorer.Application")<<

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
0
 

Author Comment

by:tomandlis
ID: 11845179
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.innerHTML = "starting"
          sUrl = "http://www.aspfree.com"

          const READYSTATE_COMPLETE = 4
          on error resume next

          Set oBrowser = CreateObject("InternetExplorer.Application")

          if err.number <> 0 then          
               document.all.whatsup.innerHTML = "set your ie default tools-options-security-default 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.innerHTML = "done"
     end function

      function FWake(linkcase)
            document.all.whatsup.innerHTML = "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.innerHTML = oBrowser.Document.body.innerHTML
            end if
      end function


      Function bClickLink(sHrefFrag)
            bComplete = true
            bClickLink = false
            Dim x , i
            x = oBrowser.Document.links.Length
            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.innerHTML = "<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.innerHTML = "Sleeping";
            window.setTimeout( sFunc, 5000);
      }
</SCRIPT>
</head>
<body onload="call bUpdateAll()">
     <div id="whatsup">Nothing</div>
</body>
</html>
0
 

Author Comment

by:tomandlis
ID: 11845210
Fritz, the article says you shouldn't do it serverside.  The code above is client side.
0
 

Author Comment

by:tomandlis
ID: 11845485
hmm, I think I found a way to do it all within vbscript here:

http://www.codeproject.com/asp/webtimer.asp
0
 

Author Comment

by:tomandlis
ID: 11845551
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</title>
<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("HandleTime",950, "VBScript")
      elseif min>0 and sec=0  then
            min=min-1
            sec=59
            status=hr & ":" & min & ":" & sec
            intTimerID=setTimeOut("HandleTime",950, "VBScript")
      elseif hr>=0 and min=0 then
            hr=hr-1
            min=59
            sec=59
            status=hr & ":" & min & ":" & sec
            intTimerID=setTimeOut("HandleTime",950, "VBScript")
      end if
      End Sub
      
      Sub endtime
            cleartimeout intTimerID
              status = "Your Time Ended"
            msgbox "Time Up"
      end sub

      status=hr & ":" & min & ":" & sec
      intTimerID=setTimeOut("HandleTime",950, "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>
0
 
LVL 4

Expert Comment

by:daluu
ID: 20898024
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/
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Have you ever needed to get an ASP script to wait for a while? I have, just to let something else happen. Or in my case, to allow other stuff to happen while I was murdering my MySQL database with an update. The Original Issue This was written…
I was asked about the differences between classic ASP and ASP.NET, so let me put them down here, for reference: Let's make the introductions... Classic ASP was launched by Microsoft in 1998 and dynamically generate web pages upon user interact…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now