Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi RegSvr32 hängt - Registrierung eines COM-Objektes (https://www.delphipraxis.net/148272-regsvr32-haengt-registrierung-eines-com-objektes.html)

ralfiii 26. Feb 2010 12:06


RegSvr32 hängt - Registrierung eines COM-Objektes
 
Hallo!

Bei der Installation unserer Software tritt bei einem Kunden (lustiger weise wirklich nur bei einem) ein Problem auf:

Sowohl beim Installieren als auch beim Deinstallieren einer COM-DLL bleibt regsvr32 hängen.
CPU-Auslastung ist quasi 0.
Ich hab's mir mit dem Process Monitor angeschaut, da wird versucht die Sprach-ressourcen-DLL zu laden und danach ist's plötzlich Schluss.

Any ideas?

Dezipaitor 26. Feb 2010 12:15

Re: RegSvr32 hängt - Registrierung eines COM-Objektes
 
Nutze Process Explorer (bitte Unterschied zu ProcessMonitor bemerken).
Damit kannst du den Prozess ansehen, wie den Aufrufstack (Eingeschaften). Womöglich siehst du die Funktion, die da hängenbleibt. Das benötigt aber womöglich die MS Symbole und eine DebugDLL, die man im PE Optionen einstellt (Configure Symbols).

Astat 26. Feb 2010 13:46

Re: RegSvr32 hängt - Registrierung eines COM-Objektes
 
Zitat:

Zitat von ralfiii
Any ideas?

Ja, ist Problem beim Aufruf von DLLRegisterServer, hier wird die Library ganz normal in den Adressraum des registrierenden Prozesses geladen. Es werden die Standard Initialisierungen durchgeführt, OnCreateXX, Initialization, etc.
Wenn hier also Code ausgeführt wird, der zu diesem Zeitpunkt eigentlich noch nicht laufen sollte, z.B. wegen UnlodLibrary.
Dann kracht's.

Abhilfe:
1. Alle Initialisierungen in eine eigene aufzurufende Prozedure packen, oder nur dann Initialisierung durchführen,
wenn nicht DLLRegisterServer aufgerufen wurde.

2. Eigenen robusteren Loader verwenden.

Anbei Loader, der dementsprechend fehlertolerant ist.

Delphi-Quellcode:

program laregsvr;

uses
  windows,
  SysUtils;

type
  TRegProc = function: HRESULT; stdcall;


function SafeLoadLibrary(const Filename: String; ErrorMode: UINT): HMODULE;
var
  SaveErrorMode: UINT;
  SaveFPUControlWord: Word;
begin
  SaveErrorMode := SetErrorMode(ErrorMode);
  try
    asm FNSTCW SaveFPUControlWord end;
    try
      Result := LoadLibrary(PChar(Filename));
    finally
      asm
        FNCLEX
        FLDCW SaveFPUControlWord
      end;
    end;
  finally
    SetErrorMode(SaveErrorMode);
  end;
end;

procedure RegisterAxLib(FileName: string; RegAction: string);
var
  RegProc: TRegProc;
  DLLHandle: THandle;
  bOK: boolean;
begin
  bOK := false;
  try
    DLLHandle := SafeLoadLibrary(FileName, SEM_FAILCRITICALERRORS or
      SEM_NOGPFAULTERRORBOX or SEM_NOALIGNMENTFAULTEXCEPT or
      SEM_NOOPENFILEERRORBOX);

    if DLLHandle <> 0 then begin
      try
        @RegProc := GetProcAddress(DLLHandle, PChar(RegAction));
        bOK := ((@RegProc <> nil) and (RegProc = 0));
      finally
        FreeLibrary(DLLHandle);
      end;
    end;
  except
    Halt(10000);
  end;
  if bOK then Halt(0) else Halt(12000);
end;

begin
  RegisterAxLib(ParamStr(1), ParamStr(2))
end.
Aufruf mit RegisterAxLib('c:\myaxlib.dll', 'DllRegisterServer');
Wenn errorcode 0 dann ok, ansonsten Fehler.

lg. Astat


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz