(This entry is a work in progress and will change in the next few days. Code will be available by 5/17.)
NET 2.0 greatly simplifies all aspects of COM deployment. In this discussion I will show how easy it is to build and deploy a COM callable class using Visual Studio 2005. I will also explain how to make this callable from scripting languages like VBScript, JScript, VBA and ASP. Before I am done with this series you will have the code and a working COM callable NET 2.0 class library along with a companion setup project that is able to install and register this NET library with only a few mouse clicks.
The idea for this project started when numerous posters to the SriptingAnswers Forum, a web site built and run by Don Jones, an author, scripter and Microsoft MVP, asked if there was a way to have the "MessageBox" and "InputBox" Windows Script Host objects timeout if no input was entered. This is one oversight by the Microsoft designers of administrative scripting tools and is a potentially useful item.
Don Jones had created a replacement for these functions that can also be used to create simple dialogs from scripting languages. His "SuperInpuBox, available at http://www.ScriptingAnswers.com has also left out the timeout function. I originally though I would just go into Don's code and add a timeout but that turned out to be more complex than I thought it would be. SuperInputBox was written in VB6. Mostly VB6 projects will convert painlessly to VB.NET using the Visual Studio Migration Wizard. Not so for this code. VB.NET had issues with the Scripting Dictionary object. Rather than spend the time solving this puzzle I decided it would be faster and easier to create a separate VB.NET DLL with InputBox, MessageBox and PasswordBox functions. Here is a sample of Step 1 of the invention.
The image at the left shows the InputBox functionality. In it's final form I want it to very closely copy the normal behavior of the VB InpuBox dialog. I have given the user a caption, a prompt and an optional set of buttons to use for terminating the dialog. Here is the call method that creates this dialog.
return = oUtils.InputBox( "My Prompt", "My Caption", ,vbYesNoCancel, 30 )
response - oUtils.Answer
The return value will be set to the values VB uses for the MessageBox function plus a value of 99 to indicate that the InputBox has timed out. The call template looks like this:
retVal = InputBox ( [prompt As String],[caption As String],[default As String],[vbMBType As Integer],[seconds As Integer]).
All of the arguments should be optional. This will prevent exceptions when the scripter forgets something. The InputBox will display some text that will make it clear that the argument has not been satisfied. The defaults will be no timeout progress bar and no timeout, An OK button, a default caption and a default prompt. It will look very much like the standard VB MessageBox function.
The other Box types; PasswordBox and MessageBox, will be preset variations on the InputBox delivered as separate functions for convenience.
The power that NET 2.0 provides us makes extending and modifying this library a cinch. One thing we will be able to easily do is to add encryption to the PasswordBox function. This will allow the user to grab the encrypted password to save to a file. We could also extend the PasswordBox function to accept Windows credentials and return them as a Windows Credentials object for passing to other objects like WMI. The possibles seem limitless.
WSHUtilities can be downloaded here.
Building this in Visual Studio 2005 was trivial except for my dislike of VB as a language. To my surprise I found VB.NET 3005 to be very nice to code in. All those little things that C programmers like to do are mostly available. Putting parens on subs and functions is now possible so I can type the way I am used to. Here is the project step by step.
- Start by creating a project for a class library. I called in DotNetUtils but name it how you like. Add to the project a Windows Form. Go into the project properties and set the library to be COM Visible. Rename the default class in the class module to something useful; in my case I called it WSHUtils. Rename the class file and form if you like. Preface the class name with "<ComClass()> on the same line in front of the Class declaration. That's it. You now have a COM callable class library. Build the project to be sure you have not broken anything before we begin to add the code.
- Now add a Public function to the class named InpuBox and give it the following argument list:
Place a call to the system MessageBox inside of the function. We are just going to use this for a simple "hook-up" test.
Build the project again to look for errors.
- Now add a new Windows Forms project to the solution and call it InputBoxTest. This will be our simple test harness.. Add a reference to the previously created class library to this project. Add a button to the default form and double click it to get to the event code. In the event code add the following:
System.Windows.Forms.MessageBox.Show( "Hello World!")
- Build and run the project. Push the button. You should see a system messagebox with our "Hello World" message.
In the next installment I Will step through the coding rerquired to implement the described functionality and build the setup project. This will get us to a Script callable COM library setup file that can be installed on any Windows XP or later system. To make this work on Windows 2000 we will have to add some registry hacks to teh setup file before we are done.