http://www.developer.com/

Back to article

Writing Active Server components in Visual Basic


April 30, 1998

Active Server components are a feature of Microsoft Internet Information Server (IIS) that provide a framework for building compiled components that can be used within Web pages. Below are step-by-step instructions for building Active Server components in Visual Basic (VB) 5.0. The process involves Active Server Pages (ASP), another feature of IIS. ASP provides the ability to combine server-side scripting in the same file with HTML, allowing you to use Active Server components and create dynamic Web pages.

Tools

Here are the tools that you need to build Active Server components:

  • Windows NT Workstation 4.0
  • Visual Basic 5.0 Enterprise Edition
  • Internet Information Server 3.0 or later, or Peer Web Services (which is IIS for Windows NT Workstation)
  • duct tape (Just kidding.)

Note: You will want to install IIS on your workstation, because VB will need to reference some of the IIS libraries, and you may need to start and stop the Web server during testing.

Construction

Building an Active Server component is not hard. Here are the steps involved in the construction of a small component that performs some simple file IO operations and generates a little HTML:

  1. Create an ActiveX DLL project and set the name to "ASCExample"

  2. Add the following references:

    Microsoft Active Server Pages 1.0 Object Library

    Microsoft Scripting Runtime

  3. Add a new class to the project, and set the name to "FileIO". (Note: This name plus the project name will be used to identify your component in the registry, for example "ASCExample.FileIO").

  4. Add this code to the FileIO class.

  5. Save everything and compile. That's it.

Testing

Testing your Active Server component is easy (although debugging can get tedious). A few lines of VBScript or JavaScript in an ASP page is all that is required. Here's the test script:






	

	

	

	
	

   ASCExample Tester


    
    



   

ASCExample Tester

<% ' Create a FileIO object. set objFileIO = Server.CreateObject("ASCExample.FileIO") %>
<% ' Get some help from the FileIO object. objFileIO.help %>
<% ' Create a file for testing. strLogFileName = "c:\temp\test.log" objFileIO.appendLine strLogFileName, "This is line 1." %> strLogFileName = <%= strLogFileName %>
fileExists() => <%= CStr(objFileIO.fileExists(strLogFileName)) %>
fileSize() => <%= objFileIO.fileSize(strLogFileName) %> bytes <% ' Delete the file. objFileIO.deleteFile(strLogFileName) %>

File deleted.
fileExists() => <%= CStr(objFileIO.fileExists(strLogFileName)) %> [end]

(Note: The <% and %> are used to delimit the server-side scripting.)

To use the test script, do the following:

  • Save the script as a file called "ASCExampleTester.asp" in a Web directory that has execute permission.

  • Point your browser at
    http://localhost/<dir>/ASCExampleTester.asp</font>
    
    , where the <dir> tag is the name of the Web directory where
    ASCExampleTester.asp</font>
    
    resides.

When you run the test script, you should get the following output.

Implementation details

Basically, an Active Server component is just a VB class. What makes it different, though, is:

  • it is packaged into an ActiveX DLL.

  • it implements OnStartPage() and OneEndPage(), which are methods that are called by IIS.

OnStartPage() is called when the component is created and can be used to get references to objects that exist within the context of an ASP page. These objects can then be used for many purposes, such as writing HTML to the response that is sent to the client. This can be seen in the help() method.

OnEndPage() is called when the component is destroyed, which will happen when the current ASP page is completely processed. This method can be used to free resources, release object references (i.e., set them = Nothing), and do other clean up.

Additionally, you should notice that some of the members of the FileIO component are private and some are public. (There are no protected members, since VB does not support inheritance.) As you would expect, only the public members are visible to users of the component. Remember, though, that a good practice in OOP is to make all member variables private and implement public accessor methods for them (e.g., getFoo() and setFoo()).

Tips

Here are two tips that might be helpful when you build some of your own Active Server components:

  1. When you deploy your components to another server, you will have to copy the DLL to the IIS components directory (which is usually c:\winnt\system32\inetsrv\???) and register the components. You register them with the registration utility, regsvr32.exe (e.g. regsvr32 ASCExample.dll). You don't have to do this when developing, because VB registers the DLL for you at the end of compilation.

  2. When you use an Active Server component, IIS locks the DLL (don't ask me why) and keeps it locked even after the ASP page is processed. If you then try to update the DLL, you will get an "access denied" error. The only way to release the lock is to stop the Web server. So, during development you may be stopping and re-starting the Web server a lot.

Summary

Building Active Server components is not hard, but it does require a high-end development platform that includes Visual Basic 5.0 Enterprise Edition and Internet Information Server running on Windows NT 4.0. In general, construction involves creating classes, implementing a couple of IIS-specific methods, and compiling them into an ActiveX DLL. Additionally, when you have built your components, using them is easier than building them and requires just a few lines of server-side scripting in a Web page.

Related links

Thornton Rose currently works in the MIS department at AGCO Corporation, where he is a software developer and the Webmaster for the intranet. He can be reached via e-mail at trose@avana.net.

ASCExample Tester


Class FileIO

Usage: set o = Server.CreateObject("ASCExample.FileIO")

Methods:

  • help() - shows help
  • fileSize(strName) - returns size of named file
  • fileExists(strName) - returns True if named file exists
  • deleteFile(strName) - deletes named file
  • appendLine(strName, strLine) - appends line to file

strLogFileName = c:\temp\test.log
fileExists() => True
fileSize() => 17 bytes

File deleted.
fileExists() => False [end]


' Class FileIO

Option Explicit

Private objApplication As Application  ' Reference to Application object
Private objResponse As Response        ' Reference to Response object

' OnStartPage():
'
' This procedure is called when an instance of this class is created in an
' Active Server Page. It gets references to the Application and Response
' objects that are being used in the ASP page that created the instance of
' this class.
'
Public Sub OnStartPage(objScriptingContext As ScriptingContext)
   Set objApplication = objScriptingContext.Application()
   Set objResponse = objScriptingContext.Response()
End Sub

' OnEndPage():
'
' This procedure is called when an instance of this class is destroyed in 
' an Active Server Page. It is used to clean up object references.
'
Public Sub OnEndPage()
   Set objApplication = Nothing
   Set objResponse = Nothing
End Sub

' help():
'
' Writes help information to the response stream.
'
Public Sub help()
   objResponse.Write "

Class FileIO

" & vbCrLf objResponse.Write "Usage:" & vbCrLf objResponse.Write "set o = Server.CreateObject(""ASCExample.FileIO"")" & vbCrLf objResponse.Write "

Methods:" & vbCrLf objResponse.Write "

    " & vbCrLf objResponse.Write "
  • help() - shows help" & vbCrLf objResponse.Write "
  • fileSize(strName) - returns size of named file" & vbCrLf objResponse.Write "
  • fileExists(strName) - returns True if named file exists" & vbCrLf objResponse.Write "
  • deleteFile(strName) - deletes named file" & vbCrLf objResponse.Write "
  • appendLine(strName, strLine) - appends line to file" & vbCrLf objResponse.Write "
" & vbCrLf End Sub ' fileSize(): ' ' Returns the size of the file with the given name. ' Public Function fileSize(strFileName) As Long fileSize = FileLen(strFileName) End Function ' fileExists(): ' ' Returns True if the specified file exists. Note that the given file ' specification can contain wildcard characters. ' Public Function fileExists(strFileSpec) As Boolean fileExists = (Dir(strFileSpec) <> "") End Function ' deleteFile(): ' ' Deletes files that match the given file specification, which can include ' wildcard characters. ' Public Sub deleteFile(strFileSpec) Call Kill(strFileSpec) End Sub ' appendLine(): ' ' Appends a line to a text file (which is handy when working with log ' files.) ' Public Sub appendLine(strFileName, strLine) Dim objFileSystem As FileSystemObject Dim objStream As TextStream Set objFileSystem = New FileSystemObject Set objStream = objFileSystem.OpenTextFile(strFileName, 8, True, False) objStream.WriteLine strLine objStream.Close End Sub ' End Class FileIO [end] -->

  • Save everything and compile. That's it.

    Testing

    Testing your Active Server component is easy (although debugging can get tedious). A few lines of VBScript or JavaScript in an ASP page is all that is required. Here's the test script:

    <html> <head> <meta name="WT.qs_dlk" content="VPhEagrIZ3MAACuQ3dMAAABQ"/> <meta name="WT.qs_shmv" content="hv20141022-raker.sf.quinstreet.net"/> <meta name="inject_params" content="WT.qs_dlk=VPhEagrIZ3MAACuQ3dMAAABQ&"/> <meta http-equiv="Set-Cookie" content="inject_params=WT.qs_dlk=VPhEagrIZ3MAACuQ3dMAAABQ&; path=/; domain=developer.com;"/> <meta http-equiv="Set-Cookie" content="WMUUID=VPhEagrIZ3MAACuQ3dMAAABQ; path=/; domain=developer.com;"/> <title>ASCExample Tester</title> <script> window.webtrendsAsyncInit=function(){ var dcs=new Webtrends.dcs().init({ dcsid:"dcs38irdn10000g0vc4171yva_9y7z", domain:"www.qsstats.com", timezone:-8, i18n:true, offsite:true, download:true, downloadtypes:"xls,doc,pdf,txt,csv,zip,docx,xlsx,rar,gzip", anchor:true, javascript: true, onsitedoms:"developer.com", fpcdom:".developer.com", plugins:{ //hm:{src:"//s.webtrends.com/js/webtrends.hm.js"} } }).track(); }; (function(){ var s=document.createElement("script"); s.async=true; s.src="/imageserver/common/v10/webtrends.min.js"; var s2=document.getElementsByTagName("script")[0]; s2.parentNode.insertBefore(s,s2); }()); </script> <noscript><img alt="dcsimg" id="dcsimg" width="1" height="1" src="//www.qsstats.com/dcs38irdn10000g0vc4171yva_9y7z/njs.gif?dcsuri=/index.php/print.php/602621&amp;WT.js=No&amp;WT.tv=10.4.1&amp;dcssip=www.developer.com&amp;WT.qs_dlk=VPhEagrIZ3MAACuQ3dMAAABQ&"/></noscript> </head> <h3>ASCExample Tester</h3> <% ' Create a FileIO object. set objFileIO = Server.CreateObject("ASCExample.FileIO") %> <hr> <% ' Get some help from the FileIO object. objFileIO.help %> <hr> <% ' Create a file for testing. strLogFileName = "c:\temp\test.log" objFileIO.appendLine strLogFileName, "This is line 1." %> <!-- Get the file info. --> strLogFileName = <%= strLogFileName %><br> fileExists() => <%= CStr(objFileIO.fileExists(strLogFileName)) %><br> fileSize() => <%= objFileIO.fileSize(strLogFileName) %> bytes <% ' Delete the file. objFileIO.deleteFile(strLogFileName) %> <p> <!-- Check the file existance again. --> File deleted.<br> fileExists() => <%= CStr(objFileIO.fileExists(strLogFileName)) %> </html> [end] </pre> <!--end_section--></p> </td></tr> </table> </font> <p> <center> <div style="text-align: center;"> <!-- QS-AD: 'lb' start --> <script language="JavaScript"> var t=displayDFPTag("lb"); document.write(t); </script> <!-- QS-AD: 'lb' end --> </div> <div align="center"> <a href="/sitemap.html">Sitemap</a> | <a href="/contactus">Contact Us</a> </div> <br/> <FONT SIZE="-1" FACE="arial, helvetica"> <style type="text/css"> #developerBrand-footer { text-align:center; margin:0 auto; } #footerlinks { font-size:12px; word-spacing:1px; } #footerlinks a { color:#000000; margin:5px 0 0 0; } #itbeBrand-footer { text-align:center; margin:0 auto; } #itbusinessedge-footer { text-align:center; margin:0 auto; } #footercopyright { font-size:12px; margin:5px 0 0 0; } #developerBrandForum-footer { text-align:center; margin:0 auto; } #itbeBrandForum-footer { text-align:center; margin:0 auto; } .footerLogoClass{ text-align:center; margin:0 auto; } </style> <div id="developerBrand-footer" style="display:none"> </div> <div id="itbeBrand-footer" style="display:none"> </div> <div id="itbusinessedge-footer" style="display:none"> </div> <div id="zde-footer" style="display:none" class="footerLogoClass"> </div> <div id="baseline-footer" style="display:none" class="footerLogoClass"> </div> <div id="cinsider-footer" style="display:none" class="footerLogoClass"> </div> <div id="cioinsight-footer" style="display:none" class="footerLogoClass"> </div> <div id="eweek-footer" style="display:none" class="footerLogoClass"> </div> <div id="enterpriseappstoday-footer" style="display:none" class="footerLogoClass"> </div> <div id="eseminar-footer" style="display:none" class="footerLogoClass"> </div> <div id="wbg-footer" style="display:none" class="footerLogoClass"> </div> <div id="developerBrandForum-footer" style="display:none"> </div> <div id="itbeBrandForum-footer" style="display:none"> </div> <script language="Javascript" src="/icom_includes/footers/scripts/footerbrandingcode.js"> </script> <!-- Google Analytics --> <script src="/icom_includes/footers/scripts/ga.js" type="text/javascript"> </script> <script type="text/javascript" > <!-- hide from no js browsers delete Array.prototype.itemValidation; delete Array.prototype.isArray; var superTracker = _gat._getTracker("UA-2838492-1"); superTracker._initData(); superTracker._trackPageview(); --> </script> <script type="text/javascript" > <!-- hide from no js browsers var site_name = location.hostname; if ( site_name.indexOf("www.") != 0 ) { site_name = "www."+site_name ; } document.write("<SCR" + "IPT LANGUAGE='JavaScript1.2' SRC='/icom_includes/footers/sites/"+ site_name +".js' TYPE='text/javascript'><\/SCR" + "IPT>"); --> </script> <script type="text/javascript" > <!--hide from no js browsers pageTracker._initData(); pageTracker._trackPageview(); // --> </script> <!-- End Google Analytics --> </font> <link href='http://fonts.googleapis.com/css?family=Lato&subset=latin,latin-ext' rel='stylesheet' type='text/css'> <div id="newuserregistrationpopup"> <div id="closepopup"><a class="close" href="#"><img src="/img/registrationwelcome/close_icon.png" border="0" /></a></div> <div id="thankuptext">Thanks for your registration, follow us on our social networks to keep up-to-date</div> <div id="socialsharebtn"> <div id="socialbtns"><a href="http://o1.qnsr.com/cgi/r?WT.qs_dlk=VPhEagrIZ3MAACuQ3dMAAABQ;;n=203;c=1459370;s=8986;x=7936;f=201411241658150;u=j;z=TIMESTAMP;k=https://twitter.com/DeveloperCom" target="_blank"><img src="/img/registrationwelcome/user-register-popup-tw.png" border="0"/></a></div> <div id="socialbtns"><a href="http://o1.qnsr.com/cgi/r?WT.qs_dlk=VPhEagrIZ3MAACuQ3dMAAABQ;;n=203;c=1459370;s=8986;x=7936;f=201411241658150;u=j;z=TIMESTAMP;k=https://www.linkedin.com/company/developer-com?trk=top_nav_home" target="_blank"><img src="/img/registrationwelcome/user-register-popup-ln.png" border="0"/></a></div> <div id="socialbtns"><a href="http://o1.qnsr.com/cgi/r?WT.qs_dlk=VPhEagrIZ3MAACuQ3dMAAABQ;;n=203;c=1459370;s=8986;x=7936;f=201411241658150;u=j;z=TIMESTAMP;k=https://plus.google.com/u/0/b/117958898397590965610/+Developerdotcom/posts" target="_blank"><img src="/img/registrationwelcome/user-register-popup-gplus.png" border="0"/></a></div> <div id="socialbtns"><a href="http://o1.qnsr.com/cgi/r?WT.qs_dlk=VPhEagrIZ3MAACuQ3dMAAABQ;;n=203;c=1459370;s=8986;x=7936;f=201411241658150;u=j;z=TIMESTAMP;k=http://www.developer.com/developer/dev-25.xml" target="_blank"><img src="/img/registrationwelcome/user-register-popup-rss.png" border="0"/></a></div> </div> </div> </center> <script> $(function () { window.print(); }); </script> </body> </html>