Compartilhar via


Why Can't I Create The WScript Object?

/>

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 ask . It'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.

Comments

  • Anonymous
    October 08, 2003
    The comment has been removed

  • Anonymous
    October 08, 2003
    Yes, the Microsoft Script Control is probably what you want. It provides a simplified interface to the script engines which you can use from VB. Here's a magazine article, or do a google search to find the documentation.http://www.microsoft.com/mind/0799/script/script.asp

  • Anonymous
    October 08, 2003
    If I create a COM object using .wsc file, I can create the WScript.Shell object, but what if I would like to write to std out and read from std in (using base WScript object), from within my COM object written in JScript (it IS running in an instance of WSH isnt it?

  • Anonymous
    October 08, 2003
    No, WSCs do not run an instance of WSH. They are just COM objects like any other. Lots of people are confused by this. I'll do a blog entry.

  • Anonymous
    January 13, 2004
    The comment has been removed

  • Anonymous
    January 21, 2004
    The reason someone would want to create a WScript object in VB, is the reason I currently want to.
    I am using the MS Script Control to run a VB script file.
    The script file has WScript references in it.
    The MS Script Control throws an error "DescriptionObject required: 'Wscript'" when it comes across a such a reference.
    The MS Script Control doesn't know what Wscript is.
    It would be handy to create a Wscript object in VB and pass it to MS Script Control, so it could indentify it and run the script as intended.

    Am I missing something here?
    How do you run a VBS script from VB, when the script has a Wscript reference in it???

  • Anonymous
    January 22, 2004
    My question then would be "why are you doing that?" If you run a WSH script without WSH, it'll fail. The same way that if you run an IE script without IE or an ASP script without ASP, it'll fail.

    Why do you expect that you should be able to run a script that uses an object model and runtime environment from a program that lacks that OM and environment?

  • Anonymous
    January 22, 2004
    Why am I doing what?
    Trying to run a VB script from a VB app?
    Because it is a requirement of our system.

    I understand the problem at hand, I am just suggesting a reason why people may ask the question frequently.

    You would think in the wonderful world of COM there would be a simple way for VB to run a VBScript file.

    The incompatibility seems absurd.

    Please let me know if you have any insight on how to run a .VBS, from a VB app (or dll), where the .VBS file contains WScript functionality.

    Thank you.

  • Anonymous
    January 23, 2004
    I have tried very much to run a remote WSH script using the WSHController object, but I got the error message "ActiveX cannot create the object" when I tried the script from Windows 2000 server to Windows Me OS and I got the error "Permission denied " when I tried the script from Windows 2000 server to Windows professional OS.
    Please tell me what I can do to resolve this problem. I need to run my scripts from my server to the clients.

  • Anonymous
    March 01, 2004
    It would be usefull to have the scripting object in VB because this would permit to code program with intellisens, object viewer, compiler, syntax analysis....

  • Anonymous
    March 09, 2004
    Here is the naswer to your question "Why would you WANT to create the WScript object in a " .... " app?"

    Because I want to to run user-defined .VBS screept but not to run them as separate process.

    There is no way you can do the Sleep if you cannot access WScript.

    The problem is the deficiencies in implementation of WScript and WSH where some important function are implemented on WScript level instead of the VBS level. You guys created the problem in the first place and then you keep asking "Why would you WANT" questions.

  • Anonymous
    March 10, 2004
    I think I see what you're saying. You want to create an object that represents a script host IN PROCESS and run scripts, right?

    We wrote that object -- it's the Microsoft Script Control. You could probably write up your own script host in VB6 that runs multiple scripts in one process and has a "Sleep" method in about 100 lines of VB, or less.

  • Anonymous
    April 30, 2004
    I am trying to run a similar code for MSI installed for a windows application in .net:

    Set oShell = WScript.CreateObject ("WScript.shell")
    oShell.run "regasm TestHarnessAPI.dll /tlb:TestHarnessAPI.tlb", 8, True

    This code registers the .net assembly as a type library. Is there any other way I can do that?

  • Anonymous
    April 30, 2004
    Just use regular old "CreateObject". Again, this is a case where the method only makes sense in WSH, and therefore we don't let you use it outside of WSH. (WScript.CreateObject participates in the WSH event binding model.)

  • Anonymous
    May 10, 2004
    The comment has been removed

  • Anonymous
    May 11, 2004
    The comment has been removed

  • Anonymous
    May 13, 2004
    The comment has been removed

  • Anonymous
    May 14, 2004
    Would you also expect an ASP page written in VBScript to just work in VB? What about an IE web page written in VBScript?

    The Response object in IIS represents a web server. The window object in IE represents a web browser. The WScript object represents a script host. A VB program is none of these things, so VB doesn't implement those object models!

    You seem to be implying that there are methods that would just work in VB -- but we already put all those methods we put on other objects so that you could use them from VB. The only ones that remain are the ones that make no sense to use from VB because they rely on the hosting model in some way.

  • Anonymous
    May 14, 2004
    The comment has been removed

  • Anonymous
    May 16, 2004
    The comment has been removed

  • Anonymous
    May 16, 2004
    even i have to run a .vbs from VB and i have done it like this

    set wshshell=wscript.CreateObject("wscript.shell")

    but i am getting the error "424:Object required."

  • Anonymous
    May 17, 2004
    The comment has been removed

  • Anonymous
    May 17, 2004
    To briefly sum up:

    Quit, Sleep, and all the object creation methods integrate with the WSH event handling and timeout model, which is completely different from VB's eventing model. In VB, use Exit for Quit, loops with DoEvents for Sleep, GetObject and CreateObject for object creation and WithEvents for event binding.

    Echo has different behaviour in WScript and CScript. Use MsgBox in VB.

    And since VB6 programs are usually forms based, not console-based, the standard streams don't really make any sense.

  • Anonymous
    May 17, 2004
    The comment has been removed

  • Anonymous
    May 17, 2004

    Here is an example of what my colleague suggests for making some vb to emulate WScript :

    ' Here is Form1.frm
    ' =====
    Private Sub Command1_Click()

    MsgBox WScript.ScriptFullName

    End Sub

    Private Sub Form_Load()

    WScript.WScriptInitialise

    End Sub



    ' Here is WScript.bas
    ' =====
    Attribute VB_Name = "WScript"
    Public WScript As WScript_Type

    Private Type WScript_Type
    ScriptFullName As String
    End Type

    Function WScriptInitialise()
    WScript.ScriptFullName = App.Path
    End Function

    Function ScriptFullName()
    ScriptFullName = WScript.ScriptFullName
    End Function

    =====

    What do u think of this approach, Eric ? ... it can only emulate so much, so it's not going to be great, but with a small library to enable most of WScript operate in VB it would make it a lot simpler for me to import my VBScript to VB and also export it back to VBScript from VB, so I'm keen on expanding this to cover most of the WScript parts if possible ... but you should have allowed this originally ! ;o) ;o) only kidding ! ;o)

    anyway, roll on Longhorn, in which the scripting language meets the full development environment ... right ? in fact there is no distinction between the 2 as far as I can see, which is the way things should be in my opinion. the scripting is completely equivalent to full development it seems in .NET which is in a way what I would have liked vbscript to have been to VB6 (but I don't want 10's of millions in development of VB7 ! I just want 10 million for me ...)

  • Anonymous
    May 17, 2004
    The comment has been removed

  • Anonymous
    May 18, 2004
    Obviously I'm not explaining myself very well.

    The difference between the FSO and the WScript, the window object and the Response objects is that the FSO represents something external to the process -- it represents the file system, which can be accessed via the operating system. The operating system has thousands of standard APIs for doing just that.

    The host-provided object models represent something about the INTERNAL state of the host and therefore must be provided by the host.

    How would you implement a cocreatable WScript object? In order to make it work, you'd need to know exactly what the compilation model, language model, eventing model and threading model the host had. There are no APIs to discover that information. The only sensible way to do it is to have the HOST expose that information in its own object model.

    Is that more clear?

  • Anonymous
    May 18, 2004
    The comment has been removed

  • Anonymous
    May 26, 2004
    The comment has been removed

  • Anonymous
    May 27, 2004
    The comment has been removed

  • Anonymous
    May 27, 2004
    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

  • Anonymous
    June 02, 2004
    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 ???

  • Anonymous
    August 04, 2004
    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

  • Anonymous
    August 05, 2004
    The comment has been removed

  • Anonymous
    February 13, 2006
    The comment has been removed

  • Anonymous
    April 20, 2006
    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.

  • Anonymous
    June 12, 2006
    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.

  • Anonymous
    June 20, 2006
    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.  

  • Anonymous
    October 11, 2006
    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.

  • Anonymous
    December 06, 2006
    The comment has been removed

  • Anonymous
    January 07, 2007
    The comment has been removed

  • Anonymous
    June 06, 2007
    The comment has been removed

  • Anonymous
    September 02, 2007
    The comment has been removed

  • Anonymous
    December 25, 2007
    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.

  • Anonymous
    August 26, 2008
    I need to get the Local machine name of the client using vbscript. Then how to get the machine name without creating an obeject to the wscript.network? How ever the vbscipt is not allowing me to create the object. How come i can get the local machine name of the client

  • Anonymous
    September 30, 2008
    The comment has been removed

  • Anonymous
    December 31, 2008
    All of the comments here that support accessing the WScript object or it's functions are classic examples of over thinking a problem.  There is absolutely no need for the WScript object outside of the WSH environment. The most recent comment was that it would be nice to have the script name available from with an HTML Application.  The fact is that you already do.  Remember that HTAs run using an instance of the IE engine, therefore most browser capabilities are available to you.  Here's a simple, reusable function for use in an HTA. Function ScriptFullName strLocation = Replace(window.location, "%20", " ") strLocation = Replace(strLocation, "/", "") ScriptFullName = Right(strLocation, Len(strLocation) - 8) End Function The window.location property is used to return the URL to the current HTA.  This needs to be formatted since it is an encoded URL.  I replace the %20 entity with a space and convert the backslashes to forward slashes.  Finally, I remove the file:/// protocol. As for a Sleep function, there are several reusable sleep functions available with a quick Google search.  In a most simplistic form, you can create one using the Time functions. Sub Sleep(intSeconds) dteStart = Time() dteEnd = TimeValue(dteStart) + TimeValue(intSeconds) While dteEnd > Time() DoNothing Wend End Sub Sub DoNothing 'While/Wend has quirks when it is empty End Sub This simply takes an integer number of seconds and adds it to the current time.  It then loops over an empty subroutine until the end time is reached, indicating that the amount of sleep time has elapsed.  I've had to create an empty subroutine because the While/Wend doesn't function properly if it is empty or only contains comments.

  • Anonymous
    June 12, 2009
    The latest comment gave me a reason to revisit this post so I thought I'd add a little more useful information.  As I've said before, the WScript family of objects is not necessary in pure VB, however, the WshShell object (specifically the Popup method) IS very useful in VBA.  VBA does not provide a method of creating message boxes through the Windows API but the WshShell object's Popup method provides us with a scriptable object that can.  Here's how to use it. 'Early bound to "Windows Script Host Object Model" Dim WshShell As IWshRuntimeLibrary.WshShell Set WshShell = New IWshRuntimeLibrary.WshShell 'Or shorter syntax for early binding... Dim WshShell As New IWshRuntimeLibrary.WshShell 'Using late binding (no reference) Dim WshShell As Object Set WshShell = CreateObject("WScript.Shell")

  • Anonymous
    June 12, 2009
    PingBack from http://www.nilpo.com/2009/06/nilpo-sightings/comments-about-wscript-on-eric-lipperts-blog/

  • Anonymous
    September 03, 2009
    I would just like to see some simple examples of how to translate from WScript calls to .NET equivalent code.  I have NO background in scripts, just need to reproduce teh functionality in .NET.  Are there any articles or resources to enlighten one about the topic?  And about how to work with Active Directories in .NET?

  • Anonymous
    November 06, 2009
    The comment has been removed

  • Anonymous
    December 13, 2009
    Remove the Wscript from the CreateObject so instead of Wscript.CreateObject("Wscript.Shell") just use CreateObject("Wscript.Shell")

  • Anonymous
    March 30, 2010
    The comment has been removed

  • Anonymous
    July 21, 2010
    @MaryK: each scripting host exposes its environment in its own way. WSH exposes it through 'WScript'. IE exposes it through 'window'. Business Objects has its own way. You should have a look at the documentation of the scripting API of product and report issues to SAP. Microsoft can't do anything for you in this case. @Robert "Nilpo" Dunham: For HTA applications, the scripting host is IE. So you can (should) use window.setTimeout().

  • Anonymous
    July 27, 2010
    The comment has been removed

  • Anonymous
    February 24, 2011
    Ok, here's mine. I want to invoke a VB script from powershell using MSScriptControl. I want to produce debugging output from the VB script and WScript.Echo seems like it'd be the obvious way to do it. Unfortunately MSScriptControl doesn't seem to provide a environment object t (which would need to hook up to it's host environment)

  • Anonymous
    May 04, 2011
    The only feature of WScript that I'd like to be able to use in VBScript is .ScriptName.   I use a 3rd party software tool, Docklight, that has custom built in functions but can also run VBScript.  There is a script file (.pts) and a data file (.ptp)  that are linked together.  When I run the script file I'd like to be able to get the filename of the script file so I can create the file name for the data file and open it.  Right now I have to add a variable with the file name in every script file, but it would be a lot easier to just use something like WScript.ScriptName and be done with it.

  • Anonymous
    January 19, 2012
    @NoSimDash @RCMorey11 @dirk Read again what I wrote.  The WScript object is only available when running from cscript.exe/wscript.exe. To put it clearly; what you are asking is impossible.