Why Can't I Create The WScript Object?

Why Can't I Create The WScript Object?

Rate This
  • Comments 59

Every now and then someone will ask me why the WSH shell object and the WSH network object are creatable from Visual Basic, but the actual root WScript object is not.

 

I am always completely mystified by why people ask this!  Why would you WANT to create the WScript object in a VB app?  What would it do for you?  It isn't creatable as an in-process object because it represents the state of a WSH process, and a VB app is not a WSH process!  The whole point of the WScript object is that it represents everything about the presently running Windows Script Host.  You can get from it all kinds of properties: the name and version of the script host, the path of the running script, the arguments which were passed in, the standard streams of the process, and whether the script was set to time out or not.  None of these properties make the slightest bit of sense to access outside of a running instance of WSH!  What the heck could this possibly mean?

 

Set WScript = CreateObject("WSH.WScript")

Timeout = WScript.TimeOut

 

The timeout of what?  You've just got some object there, not a running instance of the script host. 

 

What about the methods on the object?  Again, all of them are deeply tied into the underlying script hosting mechanisms.  WScript.CreateObject, GetObject, ConnectObject and DisconnectObject manipulate WSH-owned event sinks on the script dispatch.  I discussed yesterday how deeply tied WScript.Sleep is to the underlying hosting mechanism, and WScript.Echo is not particularly interesting -- there are better ways to create a message box in VB already.

 

I just don't get it.  Why do people keep asking me to make the WScript object creatable?  I can't figure out what they think they're going to do with it once they've created it and no one ever gives me a straight answer when I askIt's like asking for the ability to create the Response object without starting ASP!  What could it possibly mean to have a Response object but no web server process?  It doesn't make any sense, so we don't let you do it.

 

We do provide an object model whereby you can spawn off WSH processes (both locally and remotely) and query their status as they run.  Perhaps that is what these people are looking for?  Remote WSH is a complicated topic in of itself, so perhaps I'll talk about that in a later blog entry.

  • I spent all day on it yesterday and my final (although quite poor, yet ingenious) solution is as follows:

    In the file Broker_Report.vbs:

    ' <!-- #Include File = "Constants.vbs" -->
    ' <!-- #Include File = "VBS-Tools.vbs" -->
    ' <!-- #Include File = "ZurichIFA-Tools.vbs" -->

    ' <%

    OpenDB
    SendBrokerReport
    CloseDB

    -- code to do stuff here ---

    ' %>

    Include the above .vbs file in a web page as it is (making sure it's not in a directory where it's served!)

    Now include this .vbs file with a bunch of others in the file reports.wsf:

    <package>

    <job id="Consultancy_Report">
    <?job debug="true" error="true" ?>

    <Script Language="VBScript" src="Constants.vbs" />
    <Script Language="VBScript" src="VBS-Tools.vbs" />
    <Script Language="VBScript" src="ZurichIFA-Tools.vbs" />
    <Script Language="VBScript" src="Consultancy_Report.vbs" />

    </job>

    <Job ID="Consultancy_Companies_Report">
    <?job debug="true" error="true" ?>


    The #Include statements are ignored in VBScript, yet used in the web pages. Windows scripting does the including via the .wsf file, meaning the script can be run from both web pages and WScript.

    Cunning, huh?

    Martin
  • yep, it's clear Eric, my cludge is silly, i know you're right. I wasn't expecting WScript.CreatObject to be replicated, just the parts that are replicatable to work and the parts that are not to be meaningless. Some parts of WScript are meaningfull from within VB, and some are not, so those parts could easily have meaning inside VB.

    By your own analogy, if, for some weird reason, my air conditioner unit had a funky Digitial Radio receiver built into it, I *could* take the airco from one vehicle to the other and still use the Digital Radio while never actually getting the airco to work, right ???
  • Very simple requirement. I want to implement single sign on for my website. People have logged onto the network before accessing the website. So without explicitly asking for them to logon to the website i want to query what is the username/domain. All this is in ASP. Any pointers ? I don't care if it is ADSI or WScript. Any ideas would be greatly helpful
  • I'm not sure I understand what you're asking.

    If the user has already logged in to an NT domain then that information will automatically be sent to the server if the server is configured to use NT security. You shouldn't ever see a password dialog box in IE if the user is already logged in to a domain and you've granted the authenticated user access to a server.

    Are you asking how you find out in the ASP page what the user is? That's easy:

    user = Request.ServerVariables("LOGON_USER")

  • RE: Wscript.Sleep in .wsc component

    Here is a quick and dirty way to sleep within a script component, which is really a call to another script outside of the component.

    Procedure with component creates Wscript.Shell object, which is used to run a separate VBScript that just contains Wscript.Sleep

    Component code:

    Sub TestSleep

    Dim WshShell

    Set WshShell = CreateObject("WScript.Shell")

    WshShell.Run "wscript.exe C:\*\TestSleep.vbs", , true

    End Sub

    TestSleep.vbs code:

    WScript.Sleep 5000

    Note: this of course does not solve issues of event handling, etc...
  • Robert,

    Your "quick and dirty" method for calling sleep was a *HUGE* help for me! Thank you so much for your slick work-around for something that shouldn't have been reliant on Wscript.
  • How sad... I hoped a WScript object might give me a workaround for some WMI timeout problems.  If I could create a WScript object in VB and do the WMI call from there, then maybe my problems would be solved.  Unfortunately, this blog erased all hope of that experiment.
  • If you want to create a script engine from VB, use the Microsoft Script Control.  You can write a VB-based script host in about three lines of code with the Script Control. However, I don't see how that's going to help your timeout problem.  The script will run in the same thread as the rest of the VB process.

    My advice would be to find a WMI forum and pose your problem to them.  
  • Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

    Private Sub Command1_Click()

       MsgBox "begin"

       Sleep 10000

       MsgBox "end"

    End Sub

    This won't spike your cpu usage either.

  • the issue is really trivial.  asp classic never implemented its own sleep function.  for a runtime that needs to be running async XMLHTTP requests & performing other async ops, not being able to enter a waitstate is... bloody criminal.  wsh is sweet, its just tragic the asp runtime is comparatively barren.  i'm sorry most people dont understand the discrepancy, but i hope you can understand asp users' frustration at a functionally incomplete runtime.  hopefully you can forgive people for not understanding that they're two totally seperate runtimes.  you did such a good job with WSH's exposed api that asp couldnt match up.

  • if all you need is a simple sleep() function within ASP object model, you can use the WScript Shell popup sub timeout property to implement. It's a dirty hack, but if your w3svc service doesn't have "interact with desktop" property enabled you won't see anything on the console, and it'll do the trick for you without any impact on the CPU.

    I was just wondering if the inner loop inside Popup does a call to win32::Sleep() and wait for events triggered by the popup window itself, or it has any additional overhead.

    any ideas?

    -----

    <pre>

    script started.

    start: [<%= time() %>]

    waiting 10 seconds...

    <%

              Set objShell = Server.CreateObject("WScript.Shell")

              objShell.Popup "", 10

    %>

    finish: [<%= time() %>]

    script terminated.

    </pre>

  • Just to get it this out there because I searched EVERYWHERE and couldn't find a reference to this:

    It appears that the bug referenced in KB 311269 (enabling remote script host by running "wscript -regserver") is also present in Windows Vista, but just running that command isn't sufficient due to all the UAC stuff. My workaround was to create a cmd file, "regservice.cmd" with a single line, the "wscript -regserver", then right-click that command file and choose "run as administrator". Evidently UAC wasn't bright enough to prompt for access on wscript, since it didn't know that the command line "-regserver" would require administrator access.

    Hope this helps somebody.

  • Let's forget Sleep in VB. I need Sleep in VBScript that is not bound to VB or WScript.exe. I have  third party product that implements user exits via VBScript (don't have to license VBA) so I have to live within the cobstraints of their developers who don't provide a Sleep feature. I know i've seen a mechanism for instantiating WScript in an old vb 4 or 5 book; it's a wierd hack, and i've used it, but i can't find my copy of the usage. Sleep is the one function missing from VBScript that is needed outside WScript.

    I know it can be done, it has been published, please just show us how.

    thanks

  • to A G: I found 2 ways of solving this problem.

    First:

    WScriptShell.Popup "Sleep",1,"Waiter"

    When using it in ASP, it doesn't show any windows, but make a timeout for 1 second, so "Loop" or "For Next" can't use 100% CPU

    Second:

    Basicly use COM coponent with Sleep function in it.

    I still searching for using Wscript.Sleep in ASP.

    to Eric Lippert's

    is it possible to use WScript.CreateObject() with Event handling and WScript.ConnectObject and so on, as in VBSript ?

    P.S Excuse my english please. I'm russian.

Page 3 of 4 (59 items) 1234