How to detect if a OCX is registered before app generates an error because it is not

I have a Delphi app and I have integrated a 3rd party PDF reader OCX, however the problem is I can't check to see if the OCX is registered (and fix the problem by registering it) before the app crashes with a Kernal32 error (because the OCX is embedded in the main form).  I know I could fix this with an installer (which registers the OCX) but it would be alot more elegant if the program could check for the proper registration and then register it before finishing initialization.  Is there any way to do this?

First thing in my main form's OnCreate I am calling this code (but unfortunately it never gets called):

procedure RegisterOCX;
var
  OCXHand: THandle;
begin
  OCXHand:=LoadLibrary('L:\APPS\Family Services\FSWorkflow\VSPDFViewerX.ocx');

  // If OCX didn't load (OCXHand = 0) then attempt to register it
  if OCXHand = 0 then
  begin
    if (GetProcAddress(OCXHand,'DllRegisterServer')<> nil) then
    begin
      StandardEurekaError('Error Registering OCX VSPDFViewerX');
    end;
  end;
  FreeLibrary(OCXHand);
end;
lgallionAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
Russell LibbyConnect With a Mentor Software Engineer, Advisory Commented:

By the way, the code you have is incorrect. The only way to call DllRegisterServer (regardless if you do it manually, or use a wrapper process like regsvr32) is to get back a valid handle from LoadLibrary.

procedure RegisterOCX;
var
  OCXHand: THandle;
begin
  OCXHand:=LoadLibrary('L:\APPS\Family Services\FSWorkflow\VSPDFViewerX.ocx');

  // If OCXHand  = 0, then you have bigger problems like: missing dll, missing dependancy dlls, etc.
  // Thers is no way to GetProcAddress at this point.

  if OCXHand = 0 then
  begin
    if (GetProcAddress(OCXHand,'DllRegisterServer')<> nil) then
    begin

 
The other comment regarding ProgIDFromCLSID is a good test indicator that an Ax/Ocx control is registered, but does not guarantee that you will actually be able to create an instance of the desired interface. The only absolute way of testing is to get an S_OK result from CoCreateInstance (this is called by CreateOleObject, CreateComObject, etc). Because of this, it doesn't hurt to make a call to CoCreateInstance first to see if an instance can be created, and if not (and you know the library path and file) you can attempt registration.

You might also check out this recent PAQ where I provide a link to an object class (something I wrote awhile back) that simplifies the loading/calling of the dll/ocx register/unregister functions.

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21919442.html
 
Using it, the application's dpr might end up looking something like this:

uses
  Forms,
  ComReg,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}
begin

  // Initialize the application
  Application.Initialize;

  // Ensure the component is registered
  with TComRegistration.Create do
  begin
     try
       // Load library and ensure loaded
        if (Load('L:\APPS\Family Services\FSWorkflow\VSPDFViewerX.ocx') = ERROR_SUCCESS) and IsLoaded and IsComLibrary then
        begin
           // Attempt registration
           if not(Perform(raRegister) = S_OK) then
              // Error handling
              StandardEurekaError('Error Registering OCX VSPDFViewerX');
        end
        else
           // Error handling
           StandardEurekaError(Format('Error Loading OCX VSPDFViewerX (%d)', [GetLastError]));
     finally
        // Free COM registration
        Free;
     end;
  end;

  // Create form
  Application.CreateForm(TForm1, Form1);

  // Run
  Application.Run;

end.
0
 
mokuleConnect With a Mentor Commented:
try to call registerOCX in dpr

begin
  Application.Initialize;

  RegisterOCX;               // try to call here

  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
0
 
Russell LibbySoftware Engineer, Advisory Commented:
You need to perform that logic in the project source BEFORE the Application creates an instance of the main form, otherwise its too late and the error will occur.

Regards,
Russell
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
Russell LibbySoftware Engineer, Advisory Commented:
Too slow on this one ;-)

Russell
0
 
Ivanov_GCommented:
Run regsvr32 YourOCX.ocx to register it (it the file exists)
0
 
atul_parmarConnect With a Mentor Commented:
Hi use ProgIDFromCLSID win32 API function and check it's return value. It requires a class guid and returns S_OK if the class is registered otherwise it returns REGDB_E_CLASSNOTREG means the class is not registered.
0
 
lgallionAuthor Commented:
Thanks guys excellent feedback!  Kudos to mokule for a quick reply, nods to atul_parmar for pointing me in a better direction and a big thanks to rllibby for a super indepth answer.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.