How many times has it been a complete pain to try to register your .DLL's on a remote server? For me it was just about an everyday issue. This article will explore how to register your DLL's on NT 4*, using ASP.
* NOTE:
This code has been tested and verified on NT4; it has proven to be unreliable on the Windows2000 Servers I tested it on. I am pretty confident that if you play around with the Permission settings in Win2K, you will be able to have it working there as well, but for now, I am focusing on NT4.
OK, let's begin. There are a few things you will need before we start.
The physical path to Regsvr32.exe on the remote computer (usually in \WINNT\System32 OR \WINNT\System32\inetsrv)
Everyone Permissions for Execute on Regsvr32.exe (Default Setting)
Now we can begin.
Fire up your ASP Editor of Choice, create a new .ASP File and name it regsvr32.asp.
The interface I came up with, is to let the developer enter a directory path (C:\inetpub\wwwRoot\DLLs) of their choice, and then iterate thru all the files in that folder and it's subfolders building a list box of all DLL's found.
Let's start at the top and work our way down.
We need to set up our Form Post variables and increase the Script Timeout since it may take a while if you specify a directory that has many Folder to traverse (like say C:)
We can now setup our Form. We will need a textbox to hold the directory path of the parent folder to start the search. This can be any valid directory. Since I am assuming you already know HTML and it is not in the scope of this article, I am just going to give you all the HTML and asp that makes up our page and then start up with building the functions.
<!-- Basic HTML Elements -->
<HTML>
<HEAD>
<TITLE>Regsvr32.asp</TITLE>
<STYLE TYPE="TEXT/CSS">
.Legend {FONT-FAMILY: veranda; FONT-SIZE: 14px;
FONT-WEIGHT: bold; COLOR: blue}
.FS {FONT-FAMILY: veranda; FONT-SIZE: 12px; BORDER-WIDTH: 4px;
BORDER-COLOR: green; MARGIN-LEFT:2px; MARGIN-RIGHT:2px}
TD {MARGIN-LEFT:6px; MARGIN-RIGHT:6px; PADDING-LEFT:12px;
PADDING-RIGHT:12px}
</STYLE>
</HEAD>
<BODY>
<FORM NAME="regForm" METHOD="POST">
<TABLE BORDER=0 CELLSPACING=6 CELLPADDING=6 MARGINWIDTH=6>
<TR>
<TD VALIGN=TOP>
<FIELDSET ID=FS1 NAME=FS1 CLASS=FS>
<LEGEND CLASS=Legend>Regsvr Functions</LEGEND>
Insert Path to DLL Directory<BR>
<INPUT TYPE=TEXT NAME="frmFolderPath" VALUE="<%=frmFolderPath%>">
<BR>
<INPUT TYPE=SUBMIT NAME=btnFileList VALUE="Build File List">
<BR>
<%
IF Request.Form("btnFileList") <> "" OR btnREG <> "" Then
Set RegisterFiles = New clsRegister
RegisterFiles.EchoB("<B>Select File</B>")
Call RegisterFiles.init(frmFolderPath)
RegisterFiles.EchoB("<BR><INPUT TYPE=SUBMIT NAME=btnREG " _
& "VALUE=" & Chr(34) & "REG/UNREG" & Chr(34) & ">")
IF Request.Form("btnREG") <> "" Then
Call RegisterFiles.Register(frmFilePath, frmMethod)
End IF
Set RegisterFiles = Nothing
End IF
%>
</FIELDSET>
</TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
Now let's start coding!
I like to use properties to share methods across functions, so lets define a Class container to allow us the use of properties and set up a property to hold an FSO object.
Class clsRegister
Private m_oFS
Public Property Let oFS(objOFS)
m_oFS = objOFS
End Property
Public Property Get oFS()
Set oFS = Server.CreateObject("Scripting.FileSystemObject")
End Property
I like to start with some Subs / Functions that make life a bit easier.
Writing out Response.Writes is a lot of extra typing, so I first create 2 Functions that automate the process a bit. The 1st just wraps a Response.Write and adds a Line Feed to the string, the 2nd does the same but also adds a <BR> tag.
Function Echo(str)
Echo = Response.Write(str & vbCrLf)
End Function
Function EchoB(str)
EchoB = Response.Write(str & "<BR>" & vbCrLf)
End Function
Destroying objects wastes a lot of coding as well, so let's automate that a bit too.
Sub Cleanup(obj)
If isObject(obj) Then
Set obj = Nothing
End IF
End Sub
A quick Subroutine to build the radio buttons on the form so the developer can choose which method they would like to run (REG / UNREG)
Sub BuildOptions
EchoB("Register: <INPUT TYPE=RADIO NAME=frmMethod VALUE=REG CHECKED>")
EchoB("unRegister: <INPUT TYPE=RADIO NAME=frmMethod VALUE=UNREG>")
End Sub
Next, we need a method to iterate the Folders of the path that will be passed in by our form text box. We will write a new subroutine that will set a reference to the parent Folder (The path passed in, and then it will call another subroutine to iterate through all those folders and files searching for DLL's.
Sub init(strRoot) 'Root to Search (c:, d:, e:)
Dim oDrive, oRootDir
IF oFS.FolderExists(strRoot) Then
IF Len(strRoot) < 3 Then 'Must Be a Drive
Set oDrive = oFS.GetDrive(strRoot)
Set oRootDir = oDrive.RootFolder
Else
Set oRootDir = oFS.GetFolder(strRoot)
End IF
Else
EchoB("<B>Folder ( " & strRoot & " ) Not Found.")
Exit Sub 'Not Found - Get out Now
End IF
setRoot = oRootDir
Echo("<SELECT NAME=" & Chr(34) & "frmDllPath" & Chr(34) & ">")
'Call the sub to Build a list box of all DLL's found
Call getAllDlls(oRootDir)
EchoB("</SELECT>")
BuildOptions 'Call Sub that builds the radio buttons
End Sub
Next we need the GetAllDlls sub that is called from init.
This sub recursively loops through the subfolders and files of the path passed in.
It looks for DLL and OCX files and throws them into a list box when found.
Sub getAllDlls(oParentFolder)
Dim oSubFolders, oFile, oFiles
Set oSubFolders = oParentFolder.SubFolders
Set opFiles = oParentFolder.Files
For Each oFile in opFiles
IF Right(lCase(oFile.Name), 4) = ".dll" _
OR Right(lCase(oFile.Name), 4) = ".ocx" Then
Echo("<OPTION VALUE=" & Chr(34) & oFile.Path _
& Chr(34) & ">" & oFile.Name & "</Option>")
End IF
Next
On Error Resume Next 'Skip Permission Denied Folders
For Each oFolder In oSubFolders 'Iterate All Subfolders
Set oFiles = oFolder.Files
For Each oFile in oFiles
IF Right(lCase(oFile.Name), 4) = ".dll" _
OR Right(lCase(oFile.Name), 4) = ".ocx" Then
Echo("<OPTION VALUE=" & Chr(34) & oFile.Path _
& Chr(34) & ">" & oFile.Name & "</Option>")
End IF
Next
'Recursive Call to get all SubFolders in the Subfolder
Call getAllDlls(oFolder)
Next
On Error GoTo 0
End Sub
Now for the routine you have all been waiting for (Drum roll)...
The Register Routine to Register /unRegister DLL's.
Make sure that you provide the correct path to your regsvr32.exe file in this sub.
Sub Register(strFilePath, regMethod)
Dim theFile, strFile, oShell, exitcode
Set theFile = oFS.GetFile(strFilePath)
strFile = theFile.Path
Set oShell = CreateObject ("WScript.Shell")
IF regMethod = "REG" Then
'Register
oShell.Run "c:\WINNT\system32\regsvr32.exe /s " _
& strFile, 0, False
exitcode = oShell.Run("c:\WINNT\system32\regsvr32.exe /s " _
& strFile, 0, False)
EchoB("regsvr32.exe exitcode = " & exitcode)
Else
'unRegister
oShell.Run "c:\WINNT\system32\regsvr32.exe /u/s " _
& strFile, 0, False
exitcode = oShell.Run("c:\WINNT\system32\regsvr32.exe /u/s " _
& strFile, 0, False)
EchoB("regsvr32.exe exitcode = " & exitcode)
End IF
Cleanup oShell
End Sub
NOTE: Regsvr32.exe returns an exitcode of 0, regardless of whether it failed or succeeded.
Also, some dll's will require either a restart of IIS, or a complete reboot of the computer.
In other words, you may want to verify that the register completed by manually trying to call it.
That is pretty much it, let's just cleanup our OFS Property when the Class terminates.
Sub Class_Terminate()
Cleanup oFS
End Sub
While this code can save a lot of time and frustration, I cannot guarantee that it will work in your environment. If permissions have been reset for regsvr32.exe, then it obviously will fail.
Here is a screenshot of calling a .dll from asp before using these functions to register it and after.
Before Registering:
After Registering try3.dll using Regsvr32.asp
Getting The Code
You can download a zip file of the code discussed in this article from here.