AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi In Konsolenanw. auf Firebird-Events reagieren?
Thema durchsuchen
Ansicht
Themen-Optionen

In Konsolenanw. auf Firebird-Events reagieren?

Ein Thema von RSE · begonnen am 5. Dez 2012 · letzter Beitrag vom 7. Dez 2012
Antwort Antwort
Seite 2 von 2     12   
tsteinmaurer

Registriert seit: 8. Sep 2008
Ort: Linz, Österreich
530 Beiträge
 
#11

AW: In Konsolenanw. auf Firebird-Events reagieren?

  Alt 5. Dez 2012, 19:46
Klappt auch mit IBDAC.

Delphi-Quellcode:
program IBDACEventConsoleTest;

{$APPTYPE CONSOLE}

uses
  SysUtils, IBC, IBCAlerter, Forms, Types, Windows;

type
  TMyEventHandler = class
  public
    procedure DoEventAlert(Sender: TObject; AEventName: string; AEventCount: Longint);
  end;

var
  conn: TIBCConnection;
  alerter: TIBCAlerter;
  isShutdown: Boolean;
  eventHandler: TMyEventHandler;

function ConsoleEventProc(CtrlType : DWord) : Bool; stdcall; far;
begin
  case CtrlType of
    CTRL_C_EVENT,
    CTRL_BREAK_EVENT,
    CTRL_CLOSE_EVENT,
    CTRL_LOGOFF_EVENT,
    CTRL_SHUTDOWN_EVENT: isShutdown := True;
  end;
  Result := True;
end;

{ TMyEventHandler }

procedure TMyEventHandler.DoEventAlert(Sender: TObject; AEventName: string; AEventCount: Integer);
begin
  Writeln(Format('Event: %s received. Count: %d', [AEventName, AEventCount]));
end;

begin
  SetConsoleCtrlHandler(@ConsoleEventProc, True);
  try
    eventHandler := TMyEventHandler.Create;
    try
      conn := TIBCConnection.Create(nil);
      try
        conn.LoginPrompt := False;
        conn.Database := 'localhost/3051:tourism.fdb';
        conn.Username := 'tourism';
        conn.Password := 'tourism';
        conn.Connect;
        alerter := TIBCAlerter.Create(nil);
        try
          alerter.OnEvent := eventHandler.DoEventAlert;
          alerter.Connection := conn;
          alerter.Events.Add('Event1');
          alerter.Active := True;
          isShutdown := False;
          while not isShutdown do
          begin
            Application.HandleMessage;
          end;
        finally
          alerter.Active := False;
          alerter.Free;
        end;
      finally
        conn.Disconnect;
        conn.Free;
      end;
    finally
      eventHandler.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Dann noch in PSQL den Event feuern und nicht vergessen zu committen.

Code:
set term !! ;
execute block
as
begin
  post_event('Event1');
end
!!
set term ; !!

commit;
Ich bekomme in der Konsole dann den entsprechenden Output aus meinem Event-Handler. Ob das jetzt hingepfuscht oder sauber ist, können uns die echten Delphi-Geeks hier sagen.
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#12

AW: In Konsolenanw. auf Firebird-Events reagieren?

  Alt 6. Dez 2012, 09:09
Ich habe gar keine Unit Forms benutzt, zumindest steht es nicht in MEINER Uses-Liste. Habe ich trotzdem ein Application-Objekt?

Ich habe dein ConsoleEventProc übernommen, diese Möglichkeit war mir noch unbekannt. So kann ich jetzt wenigstens auch darauf reagieren, dass einfach die Konsole geschlossen wird. Allerdings verstehe ich den Ablauf noch nicht ganz. ConsoleEventProc sieht bei mir genauso aus wie bei dir. Wenn isShutdown True ist, beende ich meine Aufgaben und verlasse das Programm. Wenn ich allerdings durchdebugge, dann bricht die Ausführung kurz nach (nicht bei!) Beendigung von ConsoleEventProc ab. Den Grund dafür kann ich mir nicht erklären. Die Finallys im Haupt-Begin-End-Block werden (zumindest beim Debuggen) nicht durchlaufen. Ich rufe auch nirgends Halt auf.

Ich will quasi das Beenden der Konsole (Beenden meines Prozesses von außen) unterbinden, um meinen Prozess selbst sauber beenden zu können. Ich muss dabei ggf. auch auf die Beendung des externen Prozesses warten (Ausführung des vom Firebird-Event durch mein Programm getriggerte Batch-Skript). Sind das Schwierigkeiten, die ich mit der Verwendung von Forms und TApplication verhindern könnte? Um das zu testen müsst ich das halbe Prog umschreiben...
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#13

AW: In Konsolenanw. auf Firebird-Events reagieren?

  Alt 7. Dez 2012, 10:36
Lösung: Die Prozedur ConsoleEventProc, die mit SetConsoleCtrlHandler registriert wird, läuft asynchron zum Programm in einem anderen Thread. Wenn diese Prozedur beendet wird, wird das Programm "von außen" beendet, sobald offenbar ein weiterer Thread wieder rechenzeit bekommt. Jedenfalls werden nach Beendigung der Prozedur ConsoleEventProc noch ein paar wenige Befehle ausgeführt, bevor das Programm unkontrolliert abbricht. Abhilfe: ConsoleEventProc nie beenden. Damit hat man zumindest bis zum Timeout Zeit, das Programm ordentlich zu beenden.
Delphi-Quellcode:
function ConsoleEventProc(CtrlType: DWord): Bool; stdcall; far;
begin
  // Diese Prozedur läuft asynchron zum Programm in einem eigenen Thread
  case CtrlType of
    CTRL_C_EVENT,
    CTRL_BREAK_EVENT,
    CTRL_LOGOFF_EVENT,
    CTRL_SHUTDOWN_EVENT,
    CTRL_CLOSE_EVENT:
      begin
        // Globale Variable setzen, die regelmäßig abgefragt werden muss
        Terminated := True;
        WriteLn('Shutdown Request received');
        // unendlich warten, um das Programm ordentlich beenden zu können
        // Die Unendlichkeit ist durch einen Windows-Timeout begrenzt
        Sleep(INFINITE);
        // Schließt die Konsole und bricht damit das Programm "von außen" ab
        Result := True;
      end;
    else
      Result := False; // Standard-Handler aufrufen
  end;
end;
Application ändert an der ganzen Geschichte übrigens nichts, also hab ich die Unit Forms wieder rausgeschmissen und nutze meine eigene Message-Schleife weiter.
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#14

AW: In Konsolenanw. auf Firebird-Events reagieren?

  Alt 7. Dez 2012, 11:02
Abhilfe: ConsoleEventProc nie beenden. Damit hat man zumindest bis zum Timeout Zeit, das Programm ordentlich zu beenden.
Einige Informationen dazu habe ich hier auf Stackoverflow gefunden:

http://stackoverflow.com/questions/3...-routine-issue

Selbst wenn man eine Endlosschleife einbaut, hat man ab Windows 7 nur zehn Sekunden Zeit (ab dem Eintreten des Ctrl Close Events) für den Prgrammabschluss, dann wird das Programm "abgeschossen".
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#15

AW: In Konsolenanw. auf Firebird-Events reagieren?

  Alt 7. Dez 2012, 13:36
Man hat 5 Sekunden für CTRL_CLOSE_EVENT und 20 für CTRL_LOGOFF_EVENT und CTRL_SHUTDOWN_EVENT.

http://www.codeproject.com/Articles/...Event-Handling

Auf diesen Timeout habe ich auch im Kommentar in meinem Quelltext hingewiesen. Beziffert habe ich ihn nicht, da ich weder verlässliche Quellen (Microsoft-Dokument) noch Hinweise auf Unterschiede in verschiedenen Windows-Versionen gefunden habe.
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:39 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz