Announcement

Collapse
No announcement yet.

Fremde DLL entfernen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Fremde DLL entfernen

    <pre>
    Hallo,
    gibt es eine Möglichkeit aus einem Delphi-Programm heraus eine oder
    mehrere DLL's 'abzuschießen', die von einem anderen Programm evtl. nicht korrekt freigegeben wurden? (Namen der DLL's sind bekannt)

    Ich meine mal so etwas gesehen zu haben, aber wenn man es braucht..

    Konkreter Fall ist:

    ProgA ruft DLL1, diese eine weitere DLL2 die dann Kommunikation mit ProgB
    herstellt.

    Nun wird ProgA von Delphi-Programm per PostMessage(..,WM_QUIT) beendet,
    was auch funktioniert (zumindestens verschwindet die Task im TM).
    Beenden von ProgA muss sein, damit Delphi-Prg mit ProgB kommunizieren kann
    was - sporadisch - nicht funktioniert, da offenbar DLL1 oder DLL2 die Verbindung nicht freigegeben hat (Timing...?).

    Ich möchte nun versuchen, zu testen, ob eine der DLL's nach Stoppen
    von ProgA noch geladen ist, und diese evtl. gewaltsam beenden, bevor das Delphi-Programm sie erneut lädt (dynamisch, LoadLibrary..).
    Es handelt sich nicht um Windows-OS-DLL's, sondern API-DLL's für 3270-
    Kommunikation, die sonst keine Anwendung braucht.

    Vielleicht hat ja jemand so was mal realisiert und kann mir einen Tipp
    geben.

    Gruß
    Max

    </pre>

  • #2
    Hallo,

    das "Freischiessen" von DLLs war nur unter Windows 3.x notwendig, da dort alle Anwendungen in einem gemeinsamen Adressraum ausgeführt werden. Unter Win32 wird jede 32-Bit-Anwendung in einen eigenen Adressraum ausgeführt und eine DLL kann immer nur in den Adressraum des Prozesses geladen werden. Wenn dieser Prozess terminiert, endet zwangsläufig auch die "Lebenszeit" der DLL. Allerdings nutzen die Win32-Betriebssysteme einen DLL-Cache, indem die DLLs für die eventuelle spätere erneute Nutzung im Arbeitsspeicher vorgehalten werden

    Comment


    • #3
      Hallo Andreas,

      danke für die schnelle Reaktion..
      Ist es denn möglich, eine im Cache befindliche DLL entfernen
      zu lassen?
      Bei meinem Problem sieht es so aus, als ob die Kette, die ich beschrieben habe, nicht wieder korrekt aufgelöst wurde.
      Da ich aktuell so etwas noch nicht im Einsatz habe:
      Welches Tool würdest Du empfehlen, um allgemein unter Windows
      zu debuggen? Soft-Ice soll ja ganz gut sein, leider habe ich
      es noch nicht testen können (und weiß auch nicht, ob es mir
      bei dem Problem helfen könnte).

      Gruß
      Ma

      Comment


      • #4
        Hallo,

        wie sieht die Implementierung in der DLL aus, die auf das Ereignis <b>DLL_DETACH</b> reagiert? Win32 informiert eine DLL über definierte Aufruf-Mechanismen, wenn sie von einem Prozess geladen bzw. entladen wird. Die DLL soll dann auf diese Aufruf entsprechend reagieren und die angeforderten Ressourcen wieder freigeben. Falls gewünscht, habe ich ein Beispielprojekt vorrätig, das diesen Mechanismus verwendet

        Comment


        • #5
          <pre>
          Hallo,

          das Beispielprojekt ist auf jeden Fall interessant; um selbst bessere
          DLL's erstellen zu können, als die um die es in meiner Frage geht..
          Zur Implementierung der bewußten DLL's kann ich leider nichts sagen,
          denn die sind Bestandteile von fremderstellten Produkten.
          Meine Anwendung kommuniziert mit einer 3270-Terminal-Emulation über die
          Standard-Schnittstelle HLLAPI. Letzere liegt als DLL der 3270-Emulation
          bei und wird dynamisch geladen. Anschließend wird über eine einzige
          Funktion (Entry-Point) mit fest definierten Parametern (Daten und Kommandos)
          die 3270-Emulation ferngesteuert. Mein Programm ist aber nicht das einzige,
          das über diese Schnittstelle auf die Terminal-Emulation zugreift.
          Dieses Fremdprogramm hat die - nicht abschaltbare - Eigenschaft die Emulation
          ständig anzupollen, um Screen-Änderungen festzustellen und dann zu übernehmen.
          Daher ist es notwendig, das Fremdprogramm per PostMessage() zu beenden und
          nach dem Zugriff auf die Emulation durch das eigene Programm
          wieder zu starten. Beim Beenden baut das Fremdprogramm die Kommunkation über
          die HLLAPI-DLL (und eine weitere zur Herstellung der IBM-Kompatibilität
          zur API) sporadisch offenbar nicht korrekt ab, so dass es zu Fehlern bei der
          Kontaktaufnahme zwischen meinem Delphi-Programm und der Emulation kommt und wie es schon
          im Mittelalter war: Der Überbringer der Botschaft wird geköpft... ;-)
          Ich hatte halt die Hoffnung, das man feststellen kann, ob eine/beide der beteiligten
          DLL's evtl. noch geladen und aktiv sind, um sie dann 'abzuschießen'.
          Wenn es bei WIN32 so ist, dass diese DLL's mit dem Beenden des Fremdprogrammes ebenfalls
          deaktiviert sind, dann muss wohl die Emulation selbst etwas verwirrt sein.

          Also wie gesagt, das Beispielprojekt interessiert mich dennoch!
          BTW: Auch mir fehlt die geheimnisvolle Fortsetzung des Abschnitts
          '5.6.3 Das ADO Programmiermodell' im Client/Server-Buch
          (ist wohl einem ZeilenumBRUNCH zum Opfer gefallen ;-))
          Vielleicht geht das ja im gleichen Aufwasch, wie es so schön heißt.
          Meine Email: [email protected]
          Ansonsten bin ich schon sehr gespannt auf das angekündigte WIN32-API-Buch, damit das Trio komplett wird. Gibt es schon einen konkreten Erscheinungstermin?

          Dank im Voraus
          Gruß
          Max
          <pre&gt

          Comment


          • #6
            Hallo,

            bei einer Fremd-DLLs hat man in der Tat schlechte Karten. Wenn verschiedene Anwendungen auf die Emulation zurückgreifen, wird die DLL einen Mechanismus für den prozessübergreifenden Datenaustausch verwenden. Das folgende Beispiel demonstriert einen solchen Einsatzfall. Die Variable <b>DLLProc</b> ermöglicht einer DLL die Überwachung der Betriebssystemaufrufe an ihrem Eintrittspunkt:<br>
            DLL_PROCESS_DETACH = Gibt an, daß die DLL als Ergebnis einer Beendigungsprozedur oder eines Aufrufs von FreeLibrary vom Adreßraum des aufrufenden Prozesses getrennt wird. <br>
            DLL_THREAD_ATTACH = Gibt an, daß der aktuelle Prozeß einen neuen Thread erstellt. <br>
            DLL_THREAD_DETACH = Gibt an, daß ein Thread ohne Probleme beendet wurde. <br>

            <pre>
            { ************************************************** ****************
            Source File Name : MMFShare.PAS
            Autor : Andreas Kosch
            Erstellt am : 22.04.1997
            Compiler : Delphi 3.0
            Betriebssystem : Windows 95
            Bemerkungen : Datenaustausch zwischen mehreren Prozessen
            über eine gemeinsame DLL (verwendet dazu
            Memory-Mapped-Files).
            Revisionen : -
            ************************************************** **************** }

            library MMFShare;

            uses
            SysUtils, Windows;

            type
            PMMFData = ^TMMFData;
            TMMFData = record
            sText : array[0..50] of Char;
            end;

            const
            MMFileName : PChar = 'MMFShareData';

            var
            GlobalData : PMMFData;
            MapHandle : THandle;

            (* DLL-Schnittstellenprozedur *)

            procedure GetDLLData(var AGlobalData: PMMFData); stdcall;
            begin
            // AGlobalData zeigt auf die gleiche Adresse wie GlobalData
            AGlobalData := GlobalData;
            end;

            procedure OpenSharedData;
            var
            iSize : Integer;
            begin
            // Größe der zu mappenden Datenstruktur ermitteln
            iSize := SizeOf(TMMFData);
            try
            // Memory-Mapped-File direkt in der Auslagerungsdatei anlegen
            MapHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
            0, iSize, MMFileName);
            // erste Sichheitsprüfung
            if MapHandle = 0 then
            raise Exception.Create('CreateFileMapping-Fehler: ' +
            IntToStr(GetLastError));
            // Platz in der Auslagerungsdatei in den Adreßraum des Prozesses mappen
            GlobalData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS,
            0, 0, iSize);
            // zweite Sicherheitsprüfung
            if GlobalData = nil then begin
            CloseHandle(MapHandle);
            raise Exception.Create('MapViewOfFile-Fehler: '+
            IntToStr(GetLastError));
            end;
            // die gemeinsam zu nutzende Daten initialisieren
            GlobalData^.sText := 'Daten aus der DLL MMFShare';
            except
            on E: Exception do begin
            MessageBox(0, PChar(E.Message), 'Exception in MMFSHARE',
            MB_ICONSTOP);
            end;
            end;
            end;

            (* Memory-Mapped-Files entmappen und Handle freigeben *)

            procedure CloseSharedData;
            begin
            UnmapViewOfFile(GlobalData);
            CloseHandle(MapHandle);
            end;

            (* DLL-Einsprungpunkt *)

            procedure DLLEntryPoint(dwReason: DWord);
            begin
            case dwReason of
            DLL_PROCESS_ATTACH: OpenSharedData; // DLL wird geladen
            DLL_PROCESS_DETACH: CloseSharedData; // DLL wird entladen
            end;
            end;

            exports
            GetDLLData; // Schnittstellenprozedur exportieren

            begin
            // DLL wird in den Adreßraum geladen -> DLLEntryProc aktivieren
            DllProc := @DLLEntryPoint;
            // die DLLEntryProc auch gleich aufrufen
            DLLEntryPoint(DLL_PROCESS_ATTACH);
            end.
            </pre&gt

            Comment

            Working...
            X