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 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.


Commentary from 2019:

This article produced a lot of reader feedback, much of it very frustrated.

I learned a lot from these responses. Microsoft deservedly got a lot of flack from people who resented being characterized as “Morts”; that was a terrible choice of name for an important and valuable classification of developers. But it really is the case that a significant fraction of VB and VBScript users view error messages not as the compiler and runtime helpfully pointing out their problems, but as the thing standing between them and their success.

This article also showed how much I still lacked the “beginner’s mind” at this point in my career. I was too close to the implementation details of the system; I was quite genuine when I said that I didn’t understand why so many people wanted this thing, which was to my expert mind both impossible and useless. Why would anyone want something that was obviously both impossible and useless? But of course what they wanted was a smart and understandable solution to their immediate line-of-business problems.

Were I attacking this problem space today, I’d more likely choose a design that was better factored into orthogonal, re-usable subsystems. The alphabet soup of scripting technologies that we gave users was confusing and under-documented.

A point which I did not make in this article was that the scripting team was somewhat constrained in that we did not actually write Windows Script Host originally; another team at Microsoft created it for their own purposes, and made a number of design and implementation decisions that were not what the script team would have done. We inherited that pile of code and needed to hammer it into a shape that solved the general problem. In retrospect, it might have been a better idea to start the design process from scratch, rather than trying to mold an existing tool into the shape we thought users wanted.

Summarizing a few of the points:

I need an “eval” method that takes a bunch of VBScript or JScript, executes it, and gives me the results. How should I do that?

That’s what the Microsoft Script Control is for.

Do Windows Script Components run inside an instance of Windows Script Host?

No; WSCs are just COM objects that happen to run script; they are not WSH instances.

There are useful services that WSH provides that I’d like to see usable outside of WSH, like argument parsing.

I wrote the argument parser, so thanks for that; I tried hard to make it useful and I agree that it probably should have been made available as a stand-alone service.

I want to be able to run WSH scripts outside of WSH.

You can’t run web client scripts outside of the browser, or web server scripts outside of the server; similarly, you can’t run WSH scripts outside of WSH. WSH scripts depend on specific implementation details of WSH in order to execute correctly.

I get “permission denied” errors when trying to use the Remote WSH Controller to run WSH scripts from another machine.

Good! We worked hard to make the security model of Remote WSH very locked down. We did not want to be a new vector for attacks. To use Remote WSH, you must explicitly turn on DCOM, and then also explicitly turn on Remote WSH, and then to use it, you must be a member of the administrator group on the target machine.

We did not want to ever be in a situation where someone turned on DCOM for some unrelated reason and suddenly exposed an invisible, unknown attack vector that allowed an attacker to run an arbitrary script on a machine remotely!

WSH scripts all run in their own process; I’d like to be able to run scripts all in one process, and use WScript.Sleep

Again we come back to my point that I made in a previous episode: to write a correct Sleep you need to understand how all the other code in the same process will react to that sleeping job. If you want to write scripts that all run in the same process, use the script control; if you want some of those scripts to sleep then you will have to write an implementation of the sleep method that has the semantics you want.

 

 

Leave a comment