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.

  • > Why did they not put the sleep method in WshShell or something

    I know this might be hard to believe, but in fact I am not a complete bozo. :-)

    I put it on the WScript object for a very good reason, which I blogged about here:

    http://weblogs.asp.net/ericlippert/archive/2003/10/07/53155.aspx

  • this article makes no sense to me. i like to think i'm not a complete bozo either Mr. Lippert, but I find this quite patronising. I do a lot of scripting, and sometimes I want to port that to VB with the minimum of fuss ... quite simply, to answer your question "why would you want it ?", i would say "why not ?". let's look at the situation :

    - methods/properties that make no sense within VB, let them generate an error. that's fine, but method/properties that are sensible and reasonable, just let them work in VB. again (obviously ? quite simply ? intuitively sensible ?), just let the method/properties that make sense in vbscript function in VB and it instantly

    here's another reason : "cos I don't want to waste pointless hours re-creating the wheel, etc, every time I want to port some simple (but maybe large) vbscript into a vb project". if making WScript available inside vb means that we can port 99% of vbscripts in a very simple way into vb without recreating the wheel, sitting in front of computer screens for our entire lives not interacting with other human beings and stuff like that, then on my bozo-level, yes, I would want WScript available in VB for the above (obvious?) reasons.

    remember : as I note, if a part of script makes no sense inside vb, it generates an error. ummmm, obvious ? simple ? intuitive ??? obvious, simple, intuitive are things that appeal to my bozo-world-view. with the bozo-world-view of obvious-simple-intuitive, it would mean that we have to recreate only the parts that are essential, and it causes no complexity or overhead, it's just sensible.

    if there are absolute reasons to not allow wscript in VB then fair enough, but for the above, and for trying not to waste my entire life having to recreate the wheel every time I move from vbscript to vb and vice-versa, then ... why not, mr. lippert ??????
  • 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.


  • >>> Would you also expect an ASP page written in VBScript to just work in VB? What about an IE web page written in VBScript?

    yes, I kind of do, as it seems logical to me as a design process to make those things subsets of the larger development environment that is VB and I probably would have made that a basic design point and then there never would have been this argument, you never would have to answer this question, and I would easily be able to port things from asp/vbscript to vb etc.

    for example, I don't think that you should ever have made the wscript object except as a way to access other objects. So, I don't think that you should ever have allowed things like wscipt.echo, wscript.sleep and implemented them elsewhere. I seldom use wscript.echo / sleep, *but* it is very clear that you never ever needed them in the wscript object, sleep could easily been elsewhere and echo need never have existed. then, there are such things as constructs that I use in vbscript a lot like :
    sCurrentPath = Left(WScript.ScriptFullName, Len(WScript.ScriptFullName) - Len(WScript.ScriptName) - 1)

    I will always have to rewrite this in going to VB, but that was unneccessary with simple design goals to avoid constructs like that in wscript. If you had implemented the ScriptFullName and ScriptName parts in another place, this has complete relevance within VB in returning the location of where the compiled executable is. no ambiguity, but, since these elements are inside the wscript object a lot of thigns are messed up, and you will forever have to answer this question, and I and others will always have to rewrite our scripts. It seems to me a simple situation that could have been simply avoided with some simple basic approach to absolutely minimise the explicit ways that wscript could be accessed, wscript.echo was always pointless compared to msgbox and the shell popup method etc. I see your points completely, but the existence of things like echo, sleep, scriptfullname, scriptname etc etc are always going to hang around and be an unneccessary problem that need never have happened in the first place I think !

    I guess I'll just have to be stuck with the rewriting, and you will be stuck with constantly having to answer this question that was created as a result of making these properties available, but I just wish that there was a simpler way to just grab my scritps and stuff them inside VB and get them working without having to fundamentally rewrite quite a lot of the parts ! :o(

  • I just had a look at the WSH documentation and wanted to check some of this with you ?
    From this page in the documentation : mk:@MSITStore:C:\Program%20Files\Microsoft%20Scripting\SCRIPT56.CHM::/html/wsobjwscript.htm

    Arguments Property
    - I see why this should be in the wscript object. I see your point here.

    Interactive Property
    - This is only relevant to a scripted process. I see your point here, *but* this could easily work inside VB as it simply diables all later WSH engine output and input. *simple* to have meaning within VB and VBScript (to *me*, but maybe there are good technical reasons why this could never have a sensible context from within VB ?).

    FullName Property, Name Property, Path Property, ScriptFullName, ScriptName, Version
    - Has complete relevance within VB or VBScript. I do not see any problem.

    In fact, for Name, FullName, Path, ScriptFullName, Version, Echo, Quit, Sleep have *completely unambiguous relevance within VB as well as VBScript. Don't they to you ?i.e., I would argue that it is *very* relevant that I might want to know the location of the script engine (WScript.Path) or the name of the engine (WScript.Name) or the ScriptFullName (translates to the location of the currently running exectuable for the VB compiled code) or be able to do an Echo.

    Echo Method, Quit Method, Sleep Method
    Ok, Quit only has relevance within WSH, I see your point, and also Sleep is about the WSH engine's operation, so I see that it's not as sensible outside of that context, but VB could easily do the Sleep ! Surely, Sleep could easily function outside of the context of the WSH engine, i.e. it simply pauses program execution of course ! (that's intuitively obvious, right !?) (however, again, for complex VB execution with multiple threads or something like that, this could be ambiguous and cause problems, so maybe there are good technical reasons why this could never have a sensible context from within VB ?).

    StdErr Property, StdIn Property, StdOut Property
    - ok, you say for these unambiguously in the documentation that "The StdErr property returns an object representing the standard error stream. The StdIn, StdOut, and StdErr streams can be accessed while using CScript.exe only. Attempting to access these streams while using WScript.exe produces an error.". These will clearly never work in VB and quite rightly as it does it's own seperate error handling. I completely see your point here, and this is unambiguously addressed in the documentation, hence completely clear.

    CreateObject Method, ConnectObject Method, DisconnectObject Method, GetObject Method
    - These already work from within VB right ? for calling objects etc.

    I have to say, with the above breakdown, I have a 100% conflict with your original proposal. There are *far* more reasons why many people would want these operations to work in an intuitive way from within the context of VB than to not work. It is very relevant that a VB project of mine might want to check the version of WSH installed on a system to act upon that information in my VB program ! etc etc, I see many many reasons where I would want to use the above intuitively within VB ! I'm trying to follow your argument, you are a longstanding senior Microsoft professional programmer, and I am just a MSI packaging consultant and System Administrator that does what I'm sure you would consider to be very simplistic code, but I do a lot of it, and in that regard, simple common sense leads me to the conclusion that most of the above has absolute and unambiguous (and *useful*) relevance within VB so I just can't follow the statement "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?". Sure, for Arugments or Quit etc they only have relevance within WSH, I *completely* understand your point, but the others are very relevant in VB I would argue. I would have to say that I am completely mystified by *your* point here !

    p.s. Go easy on me, but I think I'm just making valid, sensible, intuitive points here. I'm no professional programmer like you, but I cannot at all understand the restrictions that you have *chosen* (clearly this is a design choice as most of the above have complete relevance within VB) to make as part of the WSH design process with the above points in mind !
  • 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."
  • I wrote another blog entry on why Sleep is part of the WScript object. There are good reasons why all of those are integrated into the hosting model.

    But more generally -- sure, you're right. It's software. Anything is possible. We could have written a library that made VB6 act just like WSH. (Well, except for the fact that WSH was written several years after VB6. But we could have shipped VB7 with the "WSH compatible" feature.)

    We didn't, because that would have taken years of work, cost tens of millions of dollars, and we had more important stuff to do. I'm sorry if we didn't meet your needs, but there were only a tiny handful of developers, PMs, testers, writers, localizers, etc, working on the script technologies and we had our hands full implementing things like a richer project model, a security system, and remote access for WSH -- all features that people were asking for a LOT. Very few people banged on my door demanding that we implement a new version of VB that was fully compatible with Windows Script Host. In fact, you're the first one. And since there will never be a VB7, and I added the last new feature to WSH in September of 2000, I'm afraid that you're going to have to live with disappointment.
  • 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.
  • ok, Eric, but I never said that you should make VB do what *I* want or make VB7 and I never said that you should spend 10's of millions to do what *I* want. I'm not that selfish, and I don't see how you polarise it in that odd way. No, my point is simply ... objects such as FileSystemObject were implemented *after* VB6 was made, so why could WScript not have been implemented in such a way to be accessible also !? As I understand it, some of the objects written for WSH were written *well* after VB6, but *they* are accessible from VB6, but you don't say *that* should have not been made available in VB6. Creating the other WSH objects did not require VB7 and I am not advocating VB7 for WScript support either. ok, if you want to suggest that I am saying that I selfishly want Microsoft to do what I tell it to, and that I expect Microsoft to spend 10's of millions on me, then you can say such things, but note that I never suggested it, you thrust that position onto me without me coming close to that suggestion.

    Oh, and I'm not going to live with disappointment, cos I really don't care about it much. I won't get asked this question over and over and be mystified by it, as I think it's a sensible question, but you WILL get asked this question over and over, as come on, it's an obvious question ! Anyway, a friend has implemented some function bridges in vb so that most of the wscript stuff will work as written or failover sensibly if I use his library, and so far that works perfectly for the wscript.scriptfullname etc type properties. So with a totally trivial addition like this, you could have avoided these questions that mystify you over the years completely !

    By the way, I see what you mean about echo, of course it's useful for the cscript etc as you say, I didn't think on that, but again, just to stress the point, I just thought that if FileSystemObject could be implemented *after* VB6 was written and be fully accessible from VB6 then it seems odd that WScript was chosen to be restricted in such a confusing way. My only point is that really, I think it's odd to suggest that people "mystify" you by asking that question, as you chose to make that object inaccessible so it's no wonder in light of the other objects availability that people just ask in a polite way "why?" (note : it's just a question, not a demand for 10 million dollars of development). I never banged on any doors or asked for VB7 etc, and I can live with this limitation, but to be fair, I would say, it will always raise a question mark that you created this contradictory situation, not for me alone, but as people will *obviously* ask you this question over and over, since you chose to make that intuitively broken situation with *some* of these WSH objects created *after* VB6 to be accessible from VB6, but WScript to not be accessible.

    (I'm not certain that FileSystemObject was created after VB6, but I'm pretty sure it was from my memory of WSH development, and I don't want a VB7 or for Microsoft to spend 10 million dollars on my ideas of what's intuitive, in case I didn't make that clear earlier ...;o) I should keep stressing it though, it case i'm accused of selfishly wanting Microsoft to be my personal development team.).

    Your argument is reasonable, but it's not completely sound. I think that it is NOT mystifying that people ask this question; it's PERFECTLY *natural* that people ask it. Sorry, I *love* your blogs and all that, and have learned a huge amount from reading them, fascinating stuff, but on this one, I got confused on your initial point and I guess I still think it's a completely reasonable question for people to ask ! :o)

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

  • by the way, i didn't say this is a good, it's just a *crappy* hack to make porting simple vbscript to and from vb. as soon as you add any other vb in to the main form you could not take it to vbscript etc. it's just a crappy hack, but if expanded could be useful for cut/pasting functions from vbscript into and out of vb that might reference the wscript object etc. that's all it is intended to be for really. if a crappy hack sometimes serves a simple useful purpose, i'm gonna use it. don't care much for purist nonsense. pragmatism over purism i say ;o)
  • 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?
  • Let me try an analogy. You're driving along in your Honda Civic and you want to know what the exterior temperature is. You go to your local thermometer store, buy a thermometer and bolt it to the driver's side door. You crank up the air conditioning and drive on.

    Later you buy an 18 wheeler Mack truck. You still want to know what the temperature is outside, so you unscrew the thermometer from the Civic and bolt it onto the driver's side door of the Mack truck.

    Then you try to turn on the air conditioner and realize that you forgot to get the air option. No problem -- you just take the air conditioner from the Civic, right?

    No! It doesn't work that way. The air conditioner in a Civic is built specifically to take advantage of internal implementation details of the Civic engine. The control systems, the belts, the shape and position of the compressor, etc, are all specifically designed to fit into a Honda Civic.

    Your thermometer doesn't depend on the engine -- it depends on the framework of the vehicle having the right surface to bolt it to. It's behaviour depends on factors external to the vehicle. But your air conditioner not only depends on the framework of the vehicle having a particular shape, it also depends on internal engine characteristics.

    The WScript object is a lot more like the air conditioner than the thermometer. In theory could you make a general-purpose, highly configurable air conditioner that would fit in both an 18 wheeler and a Civic hatchback? Sure, but it would be a whole lot more expensive than building the air conditioner into the truck in the first place.

    Is that more clear? I think you are majorly underestimating just how tied into the hosting model the WScript object is.

    Echo, sure, whatever, you could implement that in another host without too much difficulty.

    But what about WScript.CreateObject with event binding? How the heck are you going to do that without having access to the internal connection point array that a VB6 program maintains?
  • I have a .wsf file which has several jobs inside it - it's all working very nicely - certain jobs are scheduled to run weekly/ monthly (they email out CSV reports as an attachment). I also need the ability to trigger a .WSF script from a web page. I know this can be done through a shell type command, but I want to use the proper object. My code at the moment looks like this:

    Dim wsh As Object
    Dim oScript As Object

    wsh = Server.CreateObject("WSHController")
    ' oScript = wsh.CreateScript("C:\Inetpub\wwwroot\WebApplication1\Reports\Reports.wsf //Job:Consultancy_Report //d", "localhost")
    oScript = wsh.CreateScript("C:\Inetpub\wwwroot\WebApplication1\Reports\Reports.wsf", "martin")
    oScript.Execute()

    Dim sError As String
    sError = oScript.Error.Description


    This silently logs an error in the event log, whilst pretending to work on the web page:

    Unable to start a DCOM Server: {6F201542-B482-11D2-A250-00104BD35090}. The error:
    "Access is denied. "
    Happened while starting this command:
    C:\WINDOWS\System32\wscript.exe -Embedding

    I get a different error when running it on a Windows 2003 server (where it will hopefully end up):

    System.Runtime.InteropServices.COMException: Server execution failed

    is shown on the actual web page this time.

    Any ideas - Martin.
  • I have been meaning to write a blog entry on that subject for a while, but putting it off because its kind of complicated. In order to not become "virus central", I put a lot of safeguards into Remote WSH -- DCOM must be enabled. If you enable DCOM, WSH Remote is disabled by default. If you enable it, by default only the administrator can use it.

    Also, there might be DCOM restrictions when running from ASP, I'm not sure.

    I'll write more details at some point.
Page 2 of 4 (59 items) 1234