Recent

Author Topic: Detect application terminate or system shut down  (Read 9934 times)

Dibo

  • Hero Member
  • *****
  • Posts: 1057
Detect application terminate or system shut down
« on: July 17, 2011, 01:46:50 pm »
Hi,

I have application which works in system tray. When application is terminated I must save some stuff to the local directory (configuration, buffers, cache etc.). This works fine when user terminate application, but if he shut down system when application is running, then my program doesn't save anything (tested on windows and linux). I notify that some applications (like virtualbox or skype) can hold on system closing (I get message "Application VirtualBox is runnig. Do you really want to shut down?". How can I do this same and quick save data?

Regards

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Detect application terminate or system shut down
« Reply #1 on: July 17, 2011, 03:50:18 pm »
Code: [Select]
var
  DataSaved :Boolean = False;

procedure SaveData;
begin
  {...}
  DataSaved := True;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: boolean);
begin
  if not DataSaved then
    CanClose := False;
end;     

You will not have a chance to save data anyway, only a message is shown.
« Last Edit: July 17, 2011, 04:03:14 pm by typo »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Detect application terminate or system shut down
« Reply #2 on: July 17, 2011, 06:22:31 pm »
Surely there's no platform independent way ATM. What I know so far is that you can handle SIGTERM and SIGKILL sent by OS to all processes when it shuts down and from there, you reply something like "hold on".

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Detect application terminate or system shut down
« Reply #3 on: July 17, 2011, 08:27:58 pm »
Some tips in this thread for you:
http://lazarus.freepascal.org/index.php/topic,11326.msg58605.html#msg58605

Never rely on FormCloseQuery, you need  Application.OnEndSession etc if you really want to be sure to save when exit.

But on the otherhand, saving is best done when changes are. That is especially simple with class like TIniFile.

Dibo

  • Hero Member
  • *****
  • Posts: 1057
Re: Detect application terminate or system shut down
« Reply #4 on: July 17, 2011, 10:09:03 pm »
I did not test your solutions on windows yet, but on linux none work  :-\. I tried with SIGTERM too (code from FPC documentation):
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  7.   cthreads,
  8.   {$ENDIF}{$ENDIF}
  9.   Interfaces, // this includes the LCL widgetset
  10.   Forms, Unit1
  11.   { you can add units after this }, classes, BaseUnix;
  12.  
  13. Var
  14.    oa,na : PSigActionRec;
  15.  
  16. {$R *.res}
  17.  
  18. Procedure DoSig(sig : cint);cdecl;
  19. var s: TStringList;
  20. begin
  21.   s := TStringList.Create;
  22.   s.Add('test');
  23.   s.SaveToFile('/home/dibo/test.txt');
  24.   s.Free;
  25.   halt(1);
  26. end;
  27.  
  28. begin
  29.    new(na);
  30.    new(oa);
  31.    na^.sa_Handler:=SigActionHandler(@DoSig);
  32.    fillchar(na^.Sa_Mask,sizeof(na^.sa_mask),#0);
  33.    na^.Sa_Flags:=0;
  34.    {$ifdef Linux}               // Linux specific
  35.      na^.Sa_Restorer:=Nil;
  36.    {$endif}
  37.    if fpSigAction(SIGTerm,na,oa)<>0 then
  38.      begin
  39.      writeln('Error: ',fpgeterrno,'.');
  40.      halt(1);
  41.      end;
  42.  
  43.   RequireDerivedFormResource := True;
  44.   Application.Initialize;
  45.   Application.CreateForm(TForm1, Form1);
  46.   Application.Run;
  47. end.  
  48.  
This work when I send signal from console (kill -15 <PID>) but doesn't work when closing system. Application.OnEndSession and OnQueryEndSession doesn't work too (maybe it is not ported in linux?). I try now with SIGKILL but fpSigAction doc say:
Quote
Sig specifies the signal, and can be any signal except SIGKILL or SIGSTOP

EDIT: fpSigAction(SIGKILL,na,oa) return 0 so I can't use this type of signal
« Last Edit: July 17, 2011, 10:13:57 pm by Dibo »

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Detect application terminate or system shut down
« Reply #5 on: July 18, 2011, 12:09:03 am »
You need to save your data when modifications occur.

Elmug

  • Hero Member
  • *****
  • Posts: 849
Re: Detect application terminate or system shut down
« Reply #6 on: July 18, 2011, 03:46:35 am »
I thought it is the Op.System which detects and warns that applicaction(s) are not closed. Shutdown is a function of the op.system, anyway.

Dibo

  • Hero Member
  • *****
  • Posts: 1057
Re: Detect application terminate or system shut down
« Reply #7 on: July 18, 2011, 08:10:55 pm »
You need to save your data when modifications occur.
With configuration I could do that, but my application handle a lot of messages in memory (they are arranged on the stack) and forward to another application via IPC, so saving each message would be very inefficient. I want save this buffers only when application is closing and don't forward all messages.

I read something about linux signals. POWEROFF doesn't send any signals to processes, only SHUTDOWN do that (but my ubuntu can't shut down, I don't know why, so I can't test it). But Application.OnEndSession works perfect on windows.

 

TinyPortal © 2005-2018