Execute program, on windows shutdown/restart

I want to execute program just before windows shutdown or restart. I can trap WM_QUERYENDSESSION, but windows prevents executing programs at this point. I could prevent stutting down, wait a while, then execute the program and post shutdown message again, but I don't know exactly what was the event (shutdown, restart, end task...)
All I want to do is execute something(PostgreSQL stop bat file in this case) before restart or shutdown.
ExcessmindAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gmayoCommented:
You can determine whether it's a logoff or a shutdown but it appears you cannot determine what *type* of shutdown (restart or switch off). It's in the lparam of the WM_QUERYENDSESSION message, but I suspect you already know that.

There is an (untested) example: http://www.nl.freepascal.org/lists/fpc-pascal/2001-July/001711.html

One other possibility is not responding to the message until the other app is done. This will cause your program to "hang" and Windows will time out and ask if you want to shut down anyway. Not a problem if the other app is quick but if it takes more than a few seconds then this is probably not the route to go down.

Geoff M.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ExcessmindAuthor Commented:
But I can't start another app, when shutdown is initiated, windows gives error message.
0
gmayoCommented:
You can't execute even between WM_QUERYENDSESSION and WM_ENDSESSION? Sorry, I misinterpreted you.

How about having the other app running continuously from when Windows starts, but standing idle? Then when it gets the message to shutdown, it performs the tasks you need, and then allows shutdown?

Geoff M.
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

ExcessmindAuthor Commented:
I wish I could do this.... as far as I know, postgresql starts with one bat file and stops with another. I want to start it and hide its console window when windows starts and end it when shutdowns or restarts. My App monitors database status, start, stop etc. similar to InterBase Guardian.

I've been trying to do this in different ways, but unfortunately nothing works. I'm completely out of idas now. Looks like I have to try different approach...

P.S. I have already tried something similar to that example posted above and it didn't work.
0
Eddie ShipmanAll-around developerCommented:
post your statup nd shutdown batch files. You should be able to write a Delphi service exexcutable to do this for you.
0
Eddie ShipmanAll-around developerCommented:
oh, btw, please explain a little further what you want to happen when there is a shutdown request.
0
ExcessmindAuthor Commented:
OK, I'm posting files:
start.bat
del C:\base\pgdata\postmaster.pid
C:
cd C:\base\bin
set HOME=C:\base\bin
set PATH=C:\base\bin;C:\base\data;C:\base\usr\local\bin;
umount -A
mount C:\base /
mount C:\base\pgdata /data
bash -c "ipc-daemon & postmaster -D /data -i --shutdown"
exit

stop.bat
C:
cd C:\base\bin
set HOME=C:\base\bin
set PATH=C:\base\bin;C:\base\data;C:\base\usr\local\bin;
umount -A
mount C:\base /
mount C:\base\pgdata /data
bash -c "pg_ctl stop -D /data"
bash pg_stop
exit

these aren't the best bat files you've seen :) but I've never tried to make them better and I have to work with this database.... So, the first one starts postgres and stays hidden while database is running. The second one executes another exe and stops postgres. I want to do this before windows shutdowns.
I can't make this as service, because it is intended to run on win98 also.
I apologize for the lengthy post and thank you for your goodwill.
0
Eddie ShipmanAll-around developerCommented:
What is the location (directory containing) of the files mount, unmount and bash?

But, you can make this a tray application. This would mean that it could be setup to run at
startup and it would also close itself upon shutdown. You place the code to stop in a function
and call it either upon shutdown or via a menu or button. Place the start code in a function
and call it in the form's create method or via a menu or button.

Once I get the directories, I'll creat one for you to show that it can work and you can do all of it
using Delphi.
0
ExcessmindAuthor Commented:
All executables are in C:\base\bin.
I agree about tray app. This is what I've started to do.

Thank you in advance.
0
Eddie ShipmanAll-around developerCommented:
OK, use this and any trayicon component you want....

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Menus, StdCtrls, ShellAPI;

type
  TForm1 = class(TForm)
    PopupMenu1: TPopupMenu;
    btnStart: TButton;
    btnStop: TButton;
    mnuStart: TMenuItem;
    mnuStop: TMenuItem;
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
    bPGStarted: Boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure Run(App, CommandLine, Directory: String);
var
  sei: TShellExecuteInfo;
begin
  ZeroMemory(@sei, sizeof(sei));
  try
    with sei do
    begin
      cbSize := SizeOf(sei);
      fMask  := SEE_MASK_NOCLOSEPROCESS;
      Wnd   := Form1.Handle;
      lpVerb := 'open';
      lpFile := PChar(App);
      lpParameters := PChar(CommandLine);
      lpDirectory := PChar(Directory);
      nShow := SW_SHOWHIDE;
    end;
  finally
    ShellExecuteEx(@sei);
  end;
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
{
Start Batch File:
del C:\base\pgdata\postmaster.pid
C:
cd C:\base\bin
set HOME=C:\base\bin
set PATH=C:\base\bin;C:\base\data;C:\base\usr\local\bin;
umount -A
mount C:\base /
mount C:\base\pgdata /data
bash -c "ipc-daemon & postmaster -D /data -i --shutdown"
}
  DeleteFile('c:\base\pgdata\postmaster.pid');
  SetCurrentDir('c:\base\bin');
  SetEnvironmentVariable(PChar('HOME'), PChar('c:\base\bin'));
  SetEnvironmentVariable(PChar('PATH'), PChar('C:\base\bin;C:\base\data;C:\base\usr\local\bin;'));
  Run('c:\base\bin\unmount.exe', '-A', 'c:\base\bin');
  Run('c:\base\bin\mount.exe', 'c:\base /', 'c:\base\bin');
  Run('c:\base\bin\mount.exe', 'c:\base\pgdata /data', 'c:\base\bin');
  Run('c:\base\bin\bash.exe', '-c "ipc-daemon & postmaster -D /data -i --shutdown"', 'c:\base\bin');
  bPGStarted := True;
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
{
Stop Batch File:
cd C:\base\bin
set HOME=C:\base\bin
set PATH=C:\base\bin;C:\base\data;C:\base\usr\local\bin;
umount -A
mount C:\base /
mount C:\base\pgdata /data
bash -c "pg_ctl stop -D /data"
bash pg_stop
}
  SetCurrentDir('c:\base\bin');
  SetEnvironmentVariable(PChar('HOME'), PChar('c:\base\bin'));
  SetEnvironmentVariable(PChar('PATH'), PChar('C:\base\bin;C:\base\data;C:\base\usr\local\bin;'));
  Run('c:\base\bin\unmount.exe', '-A', 'c:\base\bin');
  Run('c:\base\bin\mount.exe', 'c:\base /', 'c:\base\bin');
  Run('c:\base\bin\bash.exe', '-c "pg_ctl stop -D /data"', 'c:\base\bin');
  Run('c:\base\bin\bash.exe', 'pg_stop', 'c:\base\bin');
  bPGStarted := False;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if bPGStarted then
    btnStopClick(nil);
end;

end.
0
ExcessmindAuthor Commented:
I've been busy these days so I din't have time to test this, but now I've tested it and it doesn't work again. You have offered me a way to ged rid of the bat files and I thank you for this(though it is somewhat slower this way), but not a solution to my problem. When windows starts shutting down, or restarting, my application receives QUERYENSESSION, at this time I can't execute any other application. ShellExecute fails and gives error message.
0
Eddie ShipmanAll-around developerCommented:
I don't know what else to suggest, then.
0
ExcessmindAuthor Commented:
Thank you anyway
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.