سؤال

I am trying to register an Active X .ocx Library in a Delphi program i have tried the following code with out success no errors and the program runs through all of the code but when it has finished the Active X Library hasn't been registered. What am i doing wrong ?

    procedure RegisterOCX;
    type
      TRegFunc = function : HResult; stdcall;

    var
      ARegFunc : TRegFunc;
      aHandle  : THandle;
      ocxPath,AppPath  : string;
      begin
      GetDir(0, AppPath);
       try
        ocxPath := AppPath + '\VOIP.ocx';
        aHandle := LoadLibrary(PChar(ocxPath));
        if aHandle <> 0 then
        begin
          ARegFunc := GetProcAddress(aHandle,'DllRegisterServer');
          if Assigned(ARegFunc) then
          begin
            ExecAndWait('regsvr32','/s ' + ocxPath);
          end;
            FreeLibrary(aHandle);

        end;
       except
         ShowMessage('Unable to register ');
        end; 
      end;

    function ExecAndWait(const ExecuteFile, ParamString : string): boolean;
    var
      SEInfo: TShellExecuteInfo;
      ExitCode: DWORD;
    begin
      FillChar(SEInfo, SizeOf(SEInfo), 0);
      SEInfo.cbSize := SizeOf(TShellExecuteInfo);
      with SEInfo do begin
      fMask := SEE_MASK_NOCLOSEPROCESS;
      Wnd := Application.Handle;
      lpFile := PChar(ExecuteFile);
      lpParameters := PChar(ParamString);
      nShow := SW_HIDE;
    end;
    if ShellExecuteEx(@SEInfo) then
    begin
      repeat
       Application.ProcessMessages;
       GetExitCodeProcess(SEInfo.hProcess, ExitCode);
      until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
       Result:=True;
    end
    else Result:=False;
  end;   
هل كانت مفيدة؟

المحلول

You are making life hard for yourself by using regsvr32. You've gone 99% of the way to doing without. Instead of calling regsvr32, just call DllRegisterServer. After all, that's all that regsvr32 is going to do!

Your code becomes:

if Assigned(ARegFunc) then
  OleCheck(ARegFunc());

You can then remove ExecAndWait altogether. Which is nice because it saves me discussing the busy loop, and the leaked handle!

It would make sense to me to rename the variable that you called ARegFunc as DllRegisterServer. So the code might then look like this:

aHandle := LoadLibrary(PChar(ocxPath));
if aHandle = 0 then
  RaiseLastWin32Error;
try
  DllRegisterServer := GetProcAddress(aHandle,'DllRegisterServer');
  if Assigned(DllRegisterServer) then
    OleCheck(DllRegisterServer());
finally
  FreeLibrary(aHandle);
end;

The most likely failure mode for a call to DllRegisterServer will be a failure to run your registration code elevated.

As an aside, LoadLibrary returns HMODULE rather than THandle.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top