【问题标题】:Delphi: Timer in Service Stops my FileReaderDelphi:服务中的计时器停止我的 FileReader
【发布时间】:2020-10-08 08:26:09
【问题描述】:

我正在编写一个具有计时器的服务,如果 Line 具有特定的数字,它应该每 60 秒检查一次。下面是定时器的代码:

procedure TConnectionChecker.Timer2Timer(Sender: TObject);
var
  myFile: TextFile;
  sLine: string;
  fileOpenLog: TStreamWriter;
  fileOpenLogName, fileOpenLogPathName: string;

begin
  ExePath := TPath.GetDirectoryName(GetModuleName(HInstance));
  filename:= 'restult.txt';
  filePath:= TPath.Combine(exePath, 'OutputFile');
  filePathName:= TPath.Combine(filePath, filename);
  fileOpenLogName:= 'Log_fileOpen.txt';
  serviceLogPath:= TPath.Combine(exePath, 'LogFiles');
  fileOpenLogPathName:= TPath.Combine(serviceLogPath, fileOpenLogName);
  fileOpenLog := TStreamWriter.Create(TFileStream.Create(fileOpenLogPathName, fmCreate or fmShareDenyWrite));

  if not FileExists(filePathName) then
  begin
    fileOpenLog.WriteLine('File not found');
    TServiceThread.Current.Terminate;
    fileOpenLog.Free;
  end;
  fileOpenLog.WriteLine('File found');
  try
    AssignFile(myFile, filePathName);
    Reset(myFile);
    fileOpenLog.WriteLine('File opened');

    while NOT eof(myFile) do
    begin
      PingWorkedAufrufe:= PingWorkedAufrufe + 1;
      readln(myFile, sLine);
      fileOpenLog.WriteLine('Read Line: ' + sLine);
      checkIfPingWorked(sLine);
    end;
    fileOpenLog.WriteLine('EOF');

  finally
    CloseFile(myFile);
  end;
  fileOpenLog.Free;
end;

这是我的程序的代码:checkIfPingWorked:

procedure TConnectionChecker.checkIfPingWorked(ALine: String);
var
  AValue, StartOfLineToFind: String;
  checkIfPingWorkedLog: TStreamWriter;
  checkIfPingWorkedLogName, checkIfPingWorkedLogPathName: string;
begin
  ExePath := TPath.GetDirectoryName(GetModuleName(HInstance));

  StartOfLineToFind:= '    Pakete: Gesendet =';
  ip:= '...';
  fileName:= 'restult.txt';
  filepath:= TPath.Combine(exePath, 'OutputFile');
  filepathname:= TPath.Combine(filepath, fileName);
  serviceLogPath:= TPath.Combine(exePath, 'LogFiles');
  checkIfPingWorkedLogName:= 'Log_checkIfPingWorked.txt';

  checkIfPingWorkedLogPathName := TPath.Combine(serviceLogPath, checkIfPingWorkedLogName);
  checkIfPingWorkedLog := TStreamWriter.Create(TFileStream.Create(checkIfPingWorkedLogPathName, fmCreate or fmShareDenyWrite));
  checkIfPingWorkedLog.WriteLine('Zeilen werden überprüft');
  if Pos(StartOfLineToFind, ALine) = 1 then
  begin
    AValue:= Copy(ALine, 39, 1);
    if AValue = IntToStr(5) then
      checkIfPingWorkedLog.WriteLine('Success')
    else
    begin
      checkIfPingWorkedLog.WriteLine('Error');

      //Writing E-Mail...
      //Authentifizierung
      IdSMTP1.AuthType := TIdSMTPAuthenticationType.satDefault;

      //Benutzerdaten für Authentifizierung
      IdSMTP1.Username := '...';
      IdSMTP1.Password := '...';

      //Server-Daten
      IdSMTP1.Host := '...';
      IdSMTP1.Port := ...;

      IdSMTP1.Connect;

      try
        IdMessage1.From.Address := '';
        IdMessage1.Recipients.EMailAddresses := '';
        //IdMessage1.CCList.EMailAddresses := '';
        //IdMessage1.BCCList.EMailAddresses := '';
        IdMessage1.Subject := '--AUTOMATISCHE BENACHRICHTIGUNG--';
        IdMessage1.Body.Text := 'Der PC mit der IP: ' + ip + ' konnte nicht mehr erreicht werden';
        IdSMTP1.Send(IdMessage1);
      finally
        IdSMTP1.Disconnect;
      end;
      checkIfPingWorkedLog.WriteLine('Email sent');
      TServiceThread.Current.Terminate;
    end;
  end;
  checkIfPingWorkedLog.Free;
end;

但我只能阅读前两行,然后就停止了。

重要的是,我最初是作为一个普通程序编写的。它工作得很好。现在我将其转换为 Windows 服务。

【问题讨论】:

  • 你怎么知道它在 FileReader 上被阻止了?
  • 这不会解决你的问题,但我认为你应该在你的文件上使用 FindFirstChangeNotification 以避免轮询它。每次文件更新时都会通知您。那你分析一下。这比 scan always 策略消耗的资源少得多。
  • @fpiette 我做了很多日志文件,一切都很好,只有文件阅读器中的那个不是
  • 您告诉过您将普通应用程序转换为服务。普通应用程序有两种类型:控制台模式和 GUI。如果还不是控制台模式程序,请首先将您的应用程序移植到控制台模式应用程序。这将很容易调试。
  • @SebastianSchwayer 否则,请考虑让您的服务线程运行一个使用Waitable Timer 的循环来了解何时定期运行代码。

标签: file delphi timer windows-services filereader


【解决方案1】:

问题是,我到处都创建了新的日志文件。 现在我在 Service Create 上创建一个日志文件:

procedure TConnectionChecker.ServiceCreate(Sender: TObject);
var
  logFilePathName, logFileName, exePath, logFilePath: String;
begin
   ExePath := TPath.GetDirectoryName(GetModuleName(HInstance));
   logFileName:= 'log_connectionTest.txt';
   logFilePath:= TPath.Combine(exePath, 'logFile');
   logFilePathName:= TPath.Combine(logFilePath, logFileName);

   if not TDirectory.Exists(logFilePath) then
    TDirectory.CreateDirectory(logFilePath);

   swLogFile:= TStreamWriter.Create(TFileStream.Create(logFilePathName, fmCreate or fmShareDenyWrite));
end;

我做了一个程序,我要求 2 个参数(目标和文本)并将该行写入日志文件。:

procedure TConnectionChecker.WriteToLog(destination, Text: string);
begin
  swLogFile.WriteLine('[' + DateTimeToStr(now) + '] ' + destination + ' schreibt: ' + text);
end;

最后我可以在每个过程中调用它:

 WriteToLog('checkIfPingWorked', 'Success')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-08
    • 2010-09-28
    • 2012-03-05
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多