Desaware Home
Products    Purchase    Publishing    Articles   Support    Company    Contact    



Contact Desaware and order today

Sign up for Desaware's Newsletter for the latest news and tech tips.

Register Your COM components Programmatically

Using RegSvr32 on a command line window may be fine for some scenarios, but there are times where you'll want to do the registration yourself using software - for example: after downloading an updated component from an external source.

One popular use for Desaware's VersionStamper is to provide auto update capability for distributed applications. You can use VersionStamper's file scanning technology to detect which of your application files may cause a conflict or require updating. Auto updating usually consists of three operations. First, detecting which files are out of date or requires updating. Second, downloading the updated the files. And third, performing any additional cleanup or registration required in order to complete the update.

This article will explore how to determine whether the updated file requires to be registered, and describes a couple of methods that can be used to perform the registration.

Normally, when a file is updated, you will simply replace the existing file with the newer file. However, in some cases, you will also need to register the new file. Registration of an updated file is required when the file does not currently exist, either because a component is missing (in which case the file may not have been registered), or because you are adding a new component to an application. You will also need to register the file when the component's object model has changed (usually in cases where a new interface or object has been added to the component). Registering the file exposes the new interfaces for the component. Finally, you will need to register the file if you install it to a location that differs from that of the existing file.

VersionStamper provides several properties that you can use to determine whether a file needs to be registered. The most commonly used method is to check whether a registration search was done for a specific file by testing for the RTWARN_NOTINREGISTRY flag in the VerConflict object's ReferenceWarningFlags property. Usually, a registration search is performed on files that require registration before they can be used (e.g. COM controls and components). You may test for the CF_FILENOTFOUND or CF_OLDERTYPELIBVERSION flags in the VerConflict object's ConflictFlags property to determine whether a version of the file currently exists and, if so, whether the file contains an older type library version number (indicating that a newer interface was expected). These properties can help you determine whether you need to register the updated file. Or, you can just always attempt to register the updated file.

One popular method for registering files is the regsvr32.exe utility provided by Microsoft. It is widely available on most operating systems and is simple to use. You can shell the regsvr32 utility with the path of file you want to register. By including the "-s" parameter flag, regsvr32 will register the file without displaying a message box indicating whether the registration request was successful or not. You can then have your application wait until the regsvr32 utility has finished (one way of doing this is described in our article "How to find out when a Shelled Application is Closed".).

On the other hand, regsvr32.exe does not exist on all operating systems so you may want to include that file to distribute with your application - we don't know the exact Microsoft software license for distributing this file with your software but believe that it is permissible as long as you own Visual Basic and is distributing that file along with your Visual Basic application.

Another drawback for using regsvr32 is that you need to launch an external application for each file you want to register (which can definitely impact performance). More important, regsvr32 does not return any error information so your application can't determine if the registration was successful.

To understand how to avoid using regsvr32, one can begin with the question: What does regsvr32.exe actually do to register a COM file? Actually, it doesn't do much. You see, every COM file must export two functions for registration purposes - DllRegisterServer and DllUnregisterServer. All regsvr32 does is call these exported functions for the file specified. You could actually add declare statements for these function calls to your own application in order to register the selected files. But there's only one catch for Visual Basic developers. In VB6, you must specify the "library" name of the declared functions. This makes it impossible to come up with a generic mechanism to call these common exported functions for any file, because you would need to statically declare a function for each file you wanted to register.

Fortunately, there is an alternative. SpyWorks includes an indirect API function call feature that allows you to call exported functions from any file. You declare a function from the SpyWorks library in your Visual Basic code and use that to call a standard exported function such as DllRegisterServer. Both the name of the component and the name of the function you want to call can be specified at runtime. This approach allows you to incorporate better registration capabilities in your application. You no longer need to launch a separate process for each file you need to register. Plus, you can get the registration results from the function call and know whether the registration function call was successful, and the reasons for any failures that occur.

The following VB6 code demonstrates how to register a generic file using the SpyWorks indirect API function call.

' Returns 0 on success, error code on error
Private Function RegisterGenericFile(ByVal DoRegister _
As Boolean, ByVal FileToRegister As String) As Long
   Dim hmod As Long
   Dim procaddress As Long
   Dim result As Long

   hmod = LoadLibrary(FileToRegister)
   If hmod = 0 Then
      ' Unable to load the specified file, return error code
      RegisterGenericFile = Err.LastDllError
      Exit Function
   End If

   If DoRegister Then
      procaddress = GetProcAddress(hmod, "DllRegisterServer")
      procaddress = GetProcAddress(hmod, "DllUnregisterServer")
   End If

   If procaddress = 0 Then
      ' Unable to find this function, means file _
      ' cannot be registered
      FreeLibrary hmod
      RegisterGenericFile = -1 ' use your own custom error code
      Exit Function
   End If

   result = dwCallIndirect(procaddress) _
   ' SpyWorks indirectAPI function 
   RegisterGenericFile = result
   FreeLibrary hmod
End Function


For notification when new articles are available, sign up for Desaware's Newsletter.

Related Products:
Products    Purchase    Articles    Support    Company    Contact
Copyright© 2012 Desaware, Inc. All Rights Reserved.    Privacy Policy