Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Logfile von Windows7/Server 2008 Blockiert (https://www.delphipraxis.net/155557-logfile-von-windows7-server-2008-blockiert.html)

QuickAndDirty 28. Okt 2010 13:20

Logfile von Windows7/Server 2008 Blockiert
 
Hallo,
Ich benutze die unten angefügte Unit zum loggen von Dienst und Anwednungsereigniss in einer D7 Anwendung/Dienstanwendung.

Zum Schreiben in die Datei wird eine Instanz über das Interface ILOGFile erzeugt und mit Log angesprochen. Es wird immer in eine Liste(Stringsout) und in eine Datei geloggt....
Die liste soll uns hier nicht interessieren.

Das problem mit der Datei ist das ich sie in XP/W2K während der Dienst läuft öffnen und angucken kann. Auf einem Kunden Rechner der W7/W-Server2k+8 drauf hat ist die Datei nicht zu öffnen weil sie gerade benutzt wird....

Benutze zum angucken des Logs Notepad und Wordpad des jeweiligen systems....beide zeigen das selbe verhalten.

Warum ist das so blöde?


Code:
unit LogFile;

interface
uses sysutils, Classes, Forms;

type

ILogFile = interface(IInterface)
['{6BDBB5CF-77B2-4E0F-8D2C-3DD06DC1AE55}']
  Function openLogFile(alogFilePath : String) : boolean;
  Function Log(aText : String) : boolean;

  Function getLogFilepath : String;
  Function getIsOpen : boolean;
  Function getStringsOut : TStrings;
  Function getLastLogTime : TDatetime;
  Procedure setStringsOut(aLogList : TStrings);
end;


TCustomLogFile = Class(TInterfacedobject, ILogFile)
Private
  fLogFile: String;
  fIsOpen: Boolean;
  fStringsOut: TStrings;
  fFile: TextFile;
  fLastLogTime: TDateTime;
Public
  Constructor Create;virtual;
  Destructor Destroy;override;

  Function OpenLogFile(alogFilePath : String) : boolean;
  Function Log(aText : String) : boolean;

  Function getLogFilePath : String;
  Function getIsOpen : boolean;
  Function getStringsOut : TStrings;
  Procedure setStringsOut(aLogList : TStrings);
  Function getLastLogTime : TDatetime;

  Property IsOpen: boolean read getIsOpen;
  Property LogFilePath : String read getLogFilePath;
  Property StringsOut : TStrings read getStringsOut write setStringsOut;
  Property LastLogTime : TDateTime read getLastLogTime;
end;

TLogfile = class(TCustomLogFile)
public
  Constructor Create(aLogfile:String;aStringsOut:TStrings);Virtual;
  Destructor Destroy;override;
end;

var StandardLogFile:ILogFile;

implementation

Constructor TLogfile.Create(aLogfile:String;aStringsOut:TStrings);
Begin
  inherited Create;
  If alogFile <> '' then
    OpenLogFile(aLogFile);
  StringsOut := aStringsOut;
  if isOpen or assigned(StringsOut) then
    Log('Log gestartet');
end;

Destructor TLogfile.Destroy;
Begin
  try
    Log('Log beendet');
  finally
    inherited Destroy;
  end;
end;

Function TCustomLogFile.getLastLogTime : TDatetime;
begin
  Result := fLastLogTime;
end;

Constructor TCustomLogFile.Create;
Begin
  inherited;
  fLogFile:= '';
  fIsOpen:= false;
  fStringsOut:= nil;
  fLastLogTime := Now;
end;

Destructor TCustomLogFile.Destroy;
Begin
  if IsOpen then
  begin
    Closefile(fFile);
    fIsOpen := false;
  end;
  inherited;
end;

Function TCustomLogFile.openLogFile(alogFilePath : String) : boolean;
Begin
  Try
    fLogFile := alogFilePath;
    AssignFile(FFile, fLogFile);
    If not FileExists(fLogFile) then
      Rewrite(FFile)
    else
      Append(FFile);
  except
    On e:Exception do
    Begin
      flogfile := '';
      raise Exception.create(e.Message);
      fIsOpen := false;
    end;
  end;
  fIsOpen := true;
end;

Function TCustomLogFile.Log(aText : String) : boolean;
var s:String;
Begin
  try
    if StringsOut <> nil then
      StringsOut.Add(aText);
  except
    on e:Exception do
    Begin
      s := 'Interner Fehler beim Schreiben in Log-Ausgabe-Objekt. '+
           'Dies ist nur dann ein normaler Vorgang wenn die Anwendung gerade '+
           'beendet wird. Das Log-Ausgabe-Objekt wird nun nicht mehr '+
           'angesprochen : '+E.message;
      StringsOut := nil;
      try
        If isOpen then
          Writeln(ffile,DateTimeToStr(now)+#9#9+s);
      except
      end;
    end;
  end;
  if isOpen then
  Begin
    WriteLn(fFile,DateTimeToStr(now)+#9#9+aText);
    Flush(fFile);
  end;
  fLastLogTime := now;
end;

Function TCustomLogFile.getLogFilePath : String;
Begin
  result := fLogFile;
end;

Function TCustomLogFile.getIsOpen : boolean;
Begin
  result := fIsOpen;
end;

Function TCustomLogFile.getStringsOut : TStrings;
Begin
  Result := fStringsOut;
end;

Procedure TCustomLogFile.setStringsOut(aLogList : TStrings);
Begin
  fStringsOut := aLogList;
end;


end.
Aufrufen

Code:
Procedure TFormbla.FromCreate(etc:tobject);
Begin
    if Application.Tag = 0 then // Wenn kein Dienst.
      StandardLogFile.setStringsOut(PR.lines)
    else
      StandardLogFile.setStringsOut(nil);
end;


procedure TFormbla.FormDestroy(Sender: TObject);
begin
  StandardLogFile.setStringsOut(nil);
  StandardLogFile.log('');
  StandardLogFile.Log('TFormbla.FormDestroy');
end;

Procedure TFormbla.OnPlanerIdle(Sender: TObject);
Begin
  DoSelbstTest;
  // Ergebnisse Loggen....&c.
  StandardLogFile.Log('ISDN - Offene Verbindungen : ' + IntToStr(cp.OpenConnections.count));
  StandardLogFile.Log('ISDN - Listenstate        : ' + BoolToStr(cp.Listening,true));
  StandardLogFile.Log('ISDN - Message            : ' + cp.ErrorString);

end;

initialization
  Logfile.StandardLogFile := TLogFile.Create('c:\Meinprogramm', nil);

QuickAndDirty 28. Okt 2010 14:46

AW: Logfile von Windows7/Server 2008 Blockiert
 
Also im prinzip ein AssignFile, AppendFile, Writeln, Flush, closefile...mehr nicht

shmia 28. Okt 2010 15:34

AW: Logfile von Windows7/Server 2008 Blockiert
 
Beim Öffnen des Logfiles sollten die Flags SHARE_DENYREAD und ggf. auch SHARE_DENYWRITE angegeben werden.
Dann kann die Datei von deinem Logobjekt geöffnet sein und man kann trotzdem mit anderen Programmen in die Logdatei reinschauen.
Blöderweise verwendest du die steinalten Pascal-Funktionen AssignFile, AppendFile, Writeln, Flush, closefile.

QuickAndDirty 28. Okt 2010 16:07

AW: Logfile von Windows7/Server 2008 Blockiert
 
Ja aber warum ist das in XP so wie es ist ok und in W7 anders?
ich meine setzt D7 andere Shareflags oder hat W7 einfach andere default Einstellungen?

Wie würdest es fixen ? Filestream, Api verwenden???
Kann ich beim Assignfile nicht irgendwie den Sharemode angeben?

shmia 28. Okt 2010 16:55

AW: Logfile von Windows7/Server 2008 Blockiert
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1058368)
Wie würdest es fixen ? Filestream, Api verwenden???

Ich würde einen THandleStream verwenden.
Bei einem THandleStream kannst du zuvor ein (File)Handle mit der API-Funktion CreateFile()
erzeugen und dem HandleStream übergeben.
(weil CreateFile() mehr Möglichkeiten bietet als TFileStream.Create)

Zitat:

Zitat von QuickAndDirty (Beitrag 1058368)
Kann ich beim Assignfile nicht irgendwie den Sharemode angeben?

Selbst wenn es geht; das wäre Quick&Dirty!
Writeln ist ja gepuffert, aber das möchte man bei einem Logfile gerade nicht haben.

QuickAndDirty 28. Okt 2010 17:12

AW: Logfile von Windows7/Server 2008 Blockiert
 
Habe is schon auf Filestream umgestellt.... :( aber mal sehen die Methoden sind ja universell...stream ist stream und so...


@Assignfile...
Und ja es wäre QuickAndDirty aber hey....style over substance....was glaubst woher die ganzen Fenster mit Glaseffect und Farbverlauf kommen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:23 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