Wrox Press
ASPToday
       1059 Articles
  in the Solutions Library
  Log off
 
 
 
DBNetGrid  
 
ASPToday Subscriber's Article Costas Hadjisotiriou
Accessing the Windows system using ActiveX and HTML
by Costas Hadjisotiriou
Categories: Scripting
Article Rating: 4.5 (5 raters)
Published on March 11, 2003
 
Content Related Links Discussion Comments Index Entries Downloads
 
Abstract
The Microsoft Windows Script Host (WSH) provides a powerful set of automation objects that enable you to access the operating system with scripting languages such as JScript and VBScript. Internet Explorer utilizes the same scripting libraries to enable WSH scripting within HTML pages. An example of this is the HTML start page of VS.NET, where you can access the file system, launch programs, and change system settings - a type of "live" user manual. Another example would be if your web site requires local installation of a certain application, and your clients use Windows with IE4.0 and above, you could use HTML pages that can be delivered over the Web, and then employ the local scriptable objects of WSH to perform the installation. In this way the user sees a familiar interface while the power of an executable is maintained. We will create a fictitious installation application (it will not actually install anything on your system) that demonstrates Shell scripting and can be used as a template for your applications.
 

Article Information
Author Costas Hadjisotiriou
Chief Technical Editor John R. Chapman
Indexer Adrian Axinte
Reviewed by David Schultz

 
Article

Introduction to the Windows Script Host’s scriptable controls

Scripts are also useful for non-repetitive tasks as well. If a task requires you to do many things in sequence, you can turn that sequence of tasks into just one task by scripting it. The WSH libraries (Comctl32.dll, Shell32.dll, Shlwapi.dll, all under the System directory) are the components of WSH, and they allow the various script controls to be exposed via different forms of scripts. For example, in the case of a script embedded in an ASP page, the engine that interprets and runs the script code is built into Internet Information Services (IIS). If it is standalone, then the WSH itself takes care of it. In our case the script is embedded in an HTML page, so the engine component that interprets and runs the script code is loaded by the Web browser, such as Internet Explorer. i.e. from the point of view of the web programmer, this is identical to programming an ASP page – only the objects used are different. Let’s look at them in summary – the ones that we will use in this article are indicated with a red border:

  • WScript Object: Provides access to most of the objects, methods, and properties in the WSH object model.
  • WshArguments Object: Gives access to the entire collection of command-line parameters in the order in which they were originally entered.
  • WshController Object: Exposes the method CreateScript() that creates a remote script process. This allows the execution of a script file at a remote server.
  • WshEnvironment Object: Gives you access to the collection of Microsoft Windows system environment variables.
  • WshNamed Object: Provides access to the named command-line script arguments within the WshArguments object.
  • WshNetwork Object: Gives you access to the shared resources on the network to which your computer is connected.
  • WshRemote Object: Provides access to the remote script process.
  • WshRemoteError Object: Exposes the error information available when a remote script (a WshRemote object) terminates as a result of a script error.
  • WshScriptExec Object: Provides status and error information about a script run with Exec, along with access to the stdIn, stdOut, and stdErr channels.
  • WshShell Object: Gives you access to the native Windows shell functionality.
  • WshShortcut Object: Allows you to create a shortcut programmatically.
  • WshSpecialFolders Object: Allows you to access the Windows Special Folders. This provides convenient access to OS folders using standard names, regardless of the exact Windows OS version. For example, "Favorites" will be under WINNT or WINDOWS depending on the OS, but in code it need only be referred to as SpecialFolders("Favorites").
  • WshUnnamed Object: Provides access to the unnamed command-line script arguments within the WshArguments object.
  • WshUrlShortcut Object: Allows you to create a shortcut to an Internet resource, programmatically.
  • Shell Object: Represents the objects in the Windows Shell. Methods are provided to control the Shell and to execute commands within the Shell. There are also methods to obtain other Shell-related objects.
  • Folder Object: The Folder object represents a folder. It contains properties and methods that allow you to retrieve information about the folder.
  • FolderItem Object: The FolderItem object represents an item in a Shell folder (which could also be a folder). It contains properties and methods that allow you to retrieve information about the item.

Before we dive into the details of this technology let’s define a scope for our HTML Installer application.

Application definition

Our application’s aim is to supply our users with a set of HTML pages that demonstrate the usage of the various WSH objects, in a relevant manner to web programmers. The intention is to demonstrate that by writing simple scripts, as would be the case for HTML or ASP pages, many complicated operating system tasks can be performed. Our choice of an installation application aims to demonstrate that an area traditionally served by compiled executables can instead be reached over the web via script-containing HTML pages.

Requirements

For the download code to work you simply need to be working with:

  • Windows 2000, Windows 98, Windows XP, regardless of IE version. Or
  • Windows NT 4.0 with Internet Explorer 4.0+, Windows 95 with Internet Explorer 4.0+

If you are executing the pages locally, i.e. not over a web server, then the default security settings of IE are fine. It will display warnings for the ActiveX controls, prompting the user to allow them to run. This is similar to other executable installation programs. However, if you are serving the pages over the Net and users will be using them directly (i.e. without saving them locally first) then you will need to explain that their security settings should be modified as shown below.

No web site should ask this level of trust from its users without properly explaining what the downloaded web page will do.

The security settings that need to be modified are in Tools:Internet Options:Security tab. Having the Internet zone selected, click on the Custom Settings button. In the screen that appears you will need to set the "Initialize and script ActiveX Controls not marked as safe" option to "Enable" ("Prompt" will not work):

The Interface

The main HTML page is installer.html. It divides the screen in two frames, the leftmost one called menu displays the page installermenu.html, and the other called steps displays the pages to be called from links inside installermenu.html. Each step in the fictitious installation process (nothing actually gets installed) is displayed in a separate HTML page, called step1.html, step2.html etc.. Here is what the application looks like upon opening:

The first step helps the user modify his PC settings if the page is not entirely visible. Installation programs commonly ask the user to perform various tasks without giving any express guidance on how to do that. On our page, simply clicking on the Desktop control panel item hyperlink we get the appropriate system screen, without having to necessarily know how to open it:

The code that achieved this is very simple. Firstly, in installermenu.html we create an instance of the WSH using the <OBJECT> tag and the WSH root Shell object class ID:

<OBJECT ID="oShell"
    CLASSID="clsid:13709620-C279-11CE-A49E-444553540000">
</OBJECT>

A list of other class IDs for other Shell objects, like Folder and FolderItem, can be viewed at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_programming/objectmap.asp&WROXEMPTOKEN=2300906Z2lL370fkoc0nzZKS6q. We will be creating them programmatically, not via declarative HTML.

Although the Shell object could be instantiated by using a JavaScript command like the one below:

var oShell = new ActiveXObject("Shell.Application");

it is preferable to use the <OBJECT> tag so that we can refer to this oShell object from within the other screen frame. Otherwise, we would have to recreate a Shell object for every installation step that we take.

The rest of the code is inside the page step1.html. The anchor link is actually defined as:

<a href="javascript:ChangeScreen()" >Desktop control panel item</a>

which calls the JavaScript function ChangeScreen() containing a one-liner:

function ChangeScreen() {
        window.parent.menu.oShell.ControlPanelItem("desk.cpl");
}

It is really that simple. The ControlPanelItem method of the Shell object takes one argument: the filename of the control panel item to be opened. If an instance is already open it activates it. You can see a list of your PC’s control panel items in your Windows System directory – look for the .cpl extension. A second control panel item example is presented in Step 2. The text presented to the user is this:

The first link calls the ControlPanelItem method with the appwiz.cpl parameter. Try it on any Windows OS, it works with the same code.

The second link demonstrates the use of file copying and the special Windows folders enumeration. Clicking it calls the function CopyThis() whose code is shown below:

function CopyThis() {
  //copy to Desktop, represented by number 0
        var objFolderTo = window.parent.menu.oShell.NameSpace(0);
  //copy from Favorites, represented by number 6
        var objFolderFrom = window.parent.menu.oShell.NameSpace(6);
  //fill a variable with all the contained items
        var objFolderItems = objFolderFrom.Items();
  //choose to copy the first one - it is also possible to 
  //search by name, test whether it is a file or a folder etc.
  document.all.cache.value = objFolderItems.Item(0).Name;
  if (objFolderItems.Item(0) != null)
        {
      //copy the file, with Yes to All to any dialog box and 
      //ability to rename if file exists already at destination
            objFolderTo.CopyHere(objFolderItems.Item(0), 16 + 8);
        }
}

As the comments in the code explain, we use the Namespace method with a number designating a special Windows folder. For a list of these special folders’ numbers see here. In this example the folder to copy from is the Favorites folder (6) and we are copying to the Desktop (0). The Namespace method can also take a string with the full path to a folder, e.g. C:\\Windows\\Favorites on Windows 98. However, using a string has the disadvantage of needing to specify a different one for each OS to be supported.

The actual copying is performed by the CopyHere function, which takes a FolderItem object as the first argument and an optional second argument specifying various options. A full list of the options can be found here. In our case, if any messages appear during the operation we answer with "Yes to All" (16) and if the item already exists the copying proceeds by giving the file an alternative name (8). If you try this on your system you will most probably see the folder Channels copied onto your Desktop. You can easily delete it but I apologize in advance for the inconvenience – I hope you find it’s worth it for the sake of demonstrating the technology :o). The function can be used in a commercial installation application for copying files to their final destination, especially if the destination is a SpecialFolder member.

Onto Step 3, where we will actually execute a file on the user’s system:

By clicking on the browse to the folder link a browsing dialog is displayed:

Browse to the directory where you have unzipped the article’s download and click OK. You will see that a file specified by the code is opened – in this case it's a simple text file, but one could easily start up an executable or a registry entries file etc.:

The code to achieve this involves the familiar Folder and FolderItems, and a new function InvokeVerb():

function FindSetup() {
  //call method for browsing dialog, returning a Folder object
        var myFolder = window.parent.menu.oShell.BrowseForFolder(0, 
                       "Find setup folder", 0, "C:\\");
  if (myFolder!=null) {
      //fill an array with the contained FolderItems
            var objFolderItems = myFolder.Items();

            if (objFolderItems!=null) {
    //loop through the FolderItems checking for the
    //name we are searching for
    for (var i=0;i<objFolderItems.Count;i++) {
      var objFolderItem = objFolderItems.Item(i);
      if (objFolderItem.Name == "THEPLAN.TXT") {
        //invoke the default verb for this file, Open
        objFolderItem.InvokeVerb();
        break;
      } 
    }
            }
  }
}

This time we create a Folder object via the user’s browsing action. The BrowseForFolder method takes 3 required parameters and one optional. The first is the handle to the dialog window, which can be left as 0. The second is a title to display, and the third is a list of browsing options described in the BrowseForFolder page on MSDN. The fourth optional parameter specifies the highest browsing level that the user can browse to. In our case, the user cannot go higher than the root C: drive. You can also specify a special folders integer, as described before.

We then examine the Name property of each contained FolderItem and when a known name is found (THEPLAN.TXT) we invoke the default verb on the file. This is equivalent to double-clicking it, or right-clicking it and selecting the action displayed in bold:

You can choose other verbs by either typing their name, e.g. objFolderItem.InvokeVerb("edit"); or supplying an ordinal number. A list of the ordinals and available verbs is given via the FolderItemVerbs object (Verbs method of a FolderItem). You can see the usefulness in executing any file that the user has downloaded on the machine, in this user-friendly way of not requiring to switch windows and contexts.

So far we have dealt with the right-most column of the WSH Object Model diagram at the beginning of the article, namely the Shell, Folder and FolderItem objects and their methods. We will now create the WSH Shell object, which supplies the programmer with some more liberal permissions in accessing the local system. Step 4 in the HTML installation program demonstrates this by creating a file. In this occasion it is a shortcut to a web URL, placed on the Desktop:

The first link calls the following function:

function MakeShortcut() {

         var WshShell = new ActiveXObject("WScript.Shell");
         strDesktop = WshShell.SpecialFolders("Desktop");
         var oUrlLink = WshShell.CreateShortcut(strDesktop + "\\Link to Help Page.url");
         oUrlLink.TargetPath = "http://www.someurl.com";
         oUrlLink.Save();
}

Because the WScript.Shell object has more capabilities, a warning is displayed asking us whether we want to allow the object to carry out its functions. We can alert our users that this is safe to say yes to – it is no more unsafe than executing an executable installation program. However, as mentioned in the Requirements section, no website should ask this level of trust from its users without properly explaining what the downloaded web page will do. This is true of any type of installation program.

The MakeShortcut() function creates the WSH Shell object and then uses the SpecialFolders method to get a reference to the Desktop path. Don’t confuse this method, which creates a WSH Special Folders object, with the Shell’s special folders constants enumeration – see these two links for a detailed explanation: Shell Special folders constants; WSH Special Folders object. We then use the Desktop reference to create a WshUrlShortcut object via the CreateShortcut function. Finally, we set the TargetPath attribute to our imaginary help page and save the link.

The second hyperlink in Step 4 uses the scripting Shell object to minimize all the windows, so that we can check that the URL shortcut was indeed created:

function MinAll() {
  window.parent.menu.oShell.MinimizeAll();
}

The shortcut should be on your PC’s Desktop – delete it as it is just a sample:

Now, Step 5 is getting really daring as far as web pages are concerned: we will add values to the machine’s registry… and then delete them of course! This is what Step 5 consists of:

The function WriteReg() carries out the writing of values using the RegWrite() method of the WSH Shell object:

function WriteReg() {

        var WshShell = new ActiveXObject("WScript.Shell");
  WshShell.RegWrite ("HKCU\\Software\\ACME\\ASPToday\\", 1, 
"REG_DWORD");
  WshShell.RegWrite ("HKCU\\Software\\ACME\\ASPToday\\Installer", 
"CostasH", "REG_SZ");
  //assign the values to the page’s textboxes
  document.all.dword.value = WshShell.RegRead
("HKCU\\Software\\ACME\\ASPToday\\").toString();
  document.all.sz.value = WshShell.RegRead
("HKCU\\Software\\ACME\\ASPToday\\Installer");
}

When the function runs (say "Yes" to the ActiveX warning dialog), the textboxes display the values that have been registered:

To confirm that they have been written, click on the last hyperlink on the page – you will get the Run file dialog, as if you had pressed Start:Run … from the Windows interface. The function opening the dialog uses the RunFile method of the Shell object:

function RunComm() {
  window.parent.menu.oShell.FileRun();
}

Type regedit in the Run dialog and click OK :

The registry editor program opens up. You can browse to the HKEY_CURRENT_USER\Software directory and confirm that the values have been inserted:

To delete them we simply run the following function by clicking on the second hyperlink:

function DelReg() {
var WshShell = new ActiveXObject("WScript.Shell");
  WshShell.RegDelete ("HKCU\\Software\\ACME\\ASPToday\\Installer");
  WshShell.RegDelete ("HKCU\\Software\\ACME\\ASPToday\\");
  WshShell.RegDelete ("HKCU\\Software\\ACME\\");
}

The registry entries should be completely deleted. Again, a very useful way of delivering a complete installation process via a humble HTML page.

Finally, Step 6 simply presents the Shutdown dialog box, asking the user to reboot:

function CloseSystem() {
  window.parent.menu.oShell.ShutdownWindows();
}

Conclusion

We have seen only some of the capabilities of the scriptable Windows shell functions. As you can see from the documentation links, they can be very powerful in performing a wide range of administration tasks. In our example, we are assisting the user to perform a fictitious installation, demonstrating the ability to present a customized HTML interface that can function on most Windows platforms. Easy delivery, familiar interface, and single-source code are just some of the advantages.

 

Please rate this article using the form below. By telling us what you like and dislike about it we can tailor our content to meet your needs.

 
 
Rate this Article
How useful was this article?
Not useful Very useful
Brief Reader Comments: Read Comments
Your name (optional):
 
 
Content Related Links Discussion Comments Index Entries Downloads
 
Back to top