Board index » delphi » Knowing when a task closes?

Knowing when a task closes?

In my application I start several other applications using
winexec.  

How can I know if one of those other applications is close down?

A related question: is it possible to read the windows task list?

Thanks for your help,

Mike Watson
--
Mayes uk

 

Re:Knowing when a task closes?


Quote
w...@sophocles.algonet.se (Johan Alveborg) wrote:
>Mayes uk (m...@d-m-g.demon.co.uk) wrote:
>: In my application I start several other applications using
>: winexec.  
>: How can I know if one of those other applications is close down?
>: A related question: is it possible to read the windows task list?
>: Thanks for your help,
>: Mike Watson
>: --
>: Mayes uk
>Save the handle you get from WinExec() and the use the Win API
>function GetModuleUsage.
>   /Johan...!

It's not clear to me what the GetModuleUsage return value
means. I believe that when it goes to zero, it's safe to
assume the execution is finished. But is that per instance?
E.g., if I WinExec two instances of the same program operating
on different files (say), can I tell which one ends first?
Or just that they have both ended? I'd be interested to hear.

Regards,
Bengt Richter

Re:Knowing when a task closes?


On Sun, 10 Dec 1995 06:20:24 GMT, b...@accessone.com (Bengt Richter)
wrote:

Quote
>It's not clear to me what the GetModuleUsage return value
>means. I believe that when it goes to zero, it's safe to
>assume the execution is finished. But is that per instance?
>E.g., if I WinExec two instances of the same program operating
>on different files (say), can I tell which one ends first?
>Or just that they have both ended? I'd be interested to hear.

GetModuleUsage tells you the usage count, and tells you nothing about
which instances are or are not running.

WinExec returns an instance handle. You can use that instance handle
to get a task handle. You can use that task handle to get any or all
window handles for the task. You can also use the task handle to
register a notification callback (NotifyRegister) to learn when
Windows unloads the task.  You can also set a shell hook with
SetWindowsHookEx to learn about individual windows that open and
close.
--
Ray Lischner         (li...@tempest-sw.com)
Tempest Software, Corvallis, Oregon, USA

Re:Knowing when a task closes?


Quote
Mayes uk <m...@d-m-g.demon.co.uk> wrote:
>In my application I start several other applications using
>winexec.  
>How can I know if one of those other applications is close down?
>A related question: is it possible to read the windows task list?
>Thanks for your help,
>Mike Watson
>--
>Mayes uk

One alternative is to intercept the WM_CLOSE message for each window.
I am currently woring on an app that I want to use this technique in
but I don't know how to intercept messages for other windows yet.  So
I am not of any help as I am working on the same problem.  If anyone
can help me do this I will be very grateful.

Eric
e...@neta.com

Re:Knowing when a task closes?


Quote
li...@tempest-sw.com (Ray Lischner) wrote:
>GetModuleUsage tells you the usage count, and tells you nothing about
>which instances are or are not running.

I dissagree. Given:
procedure TForm1.Button1Click(Sender: TObject);
var
  FirstInstanceHandle: Integer;
  SecondInstanceHandle: Integer;
begin
  FirstInstanceHandle := WinExec('NotePad',CMDShow);
  SecondInstanceHandle := WinExec('NotePad',CMDShow);
  Label1.Caption := IntToStr(GetModuleUsage(SecondInstanceHandle));
end;

After I cleared through all the notepads on my screen I saw that
the Label's caption was '1'.
Without closing any of the notepads, I exited and ran the program
again, and the Label was sill '1'.

GetModuleUsage will return 1 because you are not passing it a handle
to the module, but rather you are passing a handle to your instance of
the module.

Re:Knowing when a task closes?


Look at the help for NotifyRegister

--
Sam Liddicott                  |   Nothing I say is to be attributed as
Campbell Scientific Ltd.       | a company statement or representation.
14-20 Field Street, Shepshed,  *----------------------------------------
Leicestershire,                             Phone: +44 (0) 1509 601141
United Kingdom. LE12 9AL                    Fax:   +44 (0) 1509 601091

Re:Knowing when a task closes?


On Thu, 14 Dec 1995 01:08:54 GMT, maddo...@tiac.net (Eric Maddox)
wrote:

Quote
>li...@tempest-sw.com (Ray Lischner) wrote:

>>GetModuleUsage tells you the usage count, and tells you nothing about
>>which instances are or are not running.

>I dissagree. Given:
...
>GetModuleUsage will return 1 because you are not passing it a handle
>to the module, but rather you are passing a handle to your instance of
>the module.

Thank you for the correction. It is so important to keep instance
handles and module handles straight, even though most Windows calls
that accept one also accept the other.
--
Ray Lischner         (li...@tempest-sw.com)
Tempest Software, Corvallis, Oregon, USA

Re:Knowing when a task closes?


Quote
li...@tempest-sw.com (Ray Lischner) wrote:
>On Thu, 14 Dec 1995 01:08:54 GMT, maddo...@tiac.net (Eric Maddox)
>wrote:
>>li...@tempest-sw.com (Ray Lischner) wrote:

>>>GetModuleUsage tells you the usage count, and tells you nothing about
>>>which instances are or are not running.

>>I dissagree. Given:
>...
>>GetModuleUsage will return 1 because you are not passing it a handle
>>to the module, but rather you are passing a handle to your instance of
>>the module.
>Thank you for the correction. It is so important to keep instance
>handles and module handles straight, even though most Windows calls
>that accept one also accept the other.
>--
>Ray Lischner         (li...@tempest-sw.com)
>Tempest Software, Corvallis, Oregon, USA

Unfortunately I've missed Eric's post, or it hasn't arrived yet. But I
decided to do a little test. And I find that GetModuleUsage is not
truly reliable as a test on the WinExec-ed instance's termination.

The reason is that there is a possibility that while away during a
ProcessMessages call the instance of interest can be terminated, and
something else can be started and given the same numerical handle.
Apparently handles are recycled in short order. I'm not sure whether
this effect is limited to multiple instances of the same module or
not. It might well not be. I wonder how many inconsistently-appearing
bugs in windows programs are due to this kind of switcheroo...

If I use the handle from GetModuleHandle, it shows total usage
consistently (including 1 for the test program itself in my case,
since it was exec-ing instances of itself). Interestingly, the counts
agree when non-zero, but the instance usage goes from 2 (parent+child
instance) to zero when the child terminates.

Perhaps the NotifyRegister route is necessary, to be correct?
(Didn't I see a post by someone encapsulating that, BTW?)

Regards,
Bengt Richter

Re:Knowing when a task closes?


Quote
In article <4b3n3v$...@news.accessone.com> b...@accessone.com (Bengt Richter) writes:

[...much good stuff removed...]

Quote
>Perhaps the NotifyRegister route is necessary, to be correct?
>(Didn't I see a post by someone encapsulating that, BTW?)
>Regards,
>Bengt Richter

I am currently working on a set of components (the base components are
working now) that do encapsulate NotifyRegister, etc.

The components include (names subject to change):

TTaskNotify:
- a non-visual component that has 4 events:
     OnStartTask, OnExitTask, OnStartDLL, OnDelModule

TTrackTask:
- a non-visual component to either start a task (application) or find a
currently running task by name, class, etc.  It will have several events
including:
     AfterStart, BeforeStart, OnExitTask, BeforeClose, AfterClose

TTrackButton:
- a speed button with similar features of TTrackTask

I thought I was ready this past weekend for external testers, but I found a
bug that occurs only after installing it on the component palette.  I have a
couple of volunteers to test it, if you are interested, e-mail me for more
information (I will be ready to test by the beginning of January--who needs
sleep.)

If anyone has suggestions on what else you would like to see included, let
me know.

My plans after this portion is working is adding events for window hooks,
and other callback type events.

Doug

Douglas W Sjoquist
Cedarville College
sjoqu...@cedarville.edu
http://www.cedarville.edu/employee/sjoquist/index.htm

Re:Knowing when a task closes?


Quote
Mayes uk (m...@d-m-g.demon.co.uk) wrote:
>: In my application I start several other applications using
>: winexec.  
>: How can I know if one of those other applications is close down?
>: A related question: is it possible to read the windows task list?
>: Thanks for your help,
>: Mike Watson
>: --
>: Mayes uk
w...@sophocles.algonet.se (Johan Alveborg) wrote:
>Save the handle you get from WinExec() and the use the Win API
>function GetModuleUsage.
>   /Johan...!

Sorry to fall into this thread like this, but I have a related
problem. I start an application, using WinExec(), saving the
taskhandle it returns. However what I need to do is close the "child"
application when I exit my program. I can of course see if the other
application is still running by using the GetModuleUsage() function,
but how can I kill it?

I tried things like
        PostAppMessage(AppHandle,WM_CLOSE,0,0);
but I got only GPF's....

Any suggestions?

Thanks in advance!

Boudewijn.

Re:Knowing when a task closes?


In article <4ce6rl$...@nosy.bart.nl> bo...@bart.nl (Boudewijn van Ingen) writes:

Quote
>Sorry to fall into this thread like this, but I have a related
>problem. I start an application, using WinExec(), saving the
>taskhandle it returns. However what I need to do is close the "child"
>application when I exit my program. I can of course see if the other
>application is still running by using the GetModuleUsage() function,
>but how can I kill it?
>Any suggestions?

Try using the following code snippet...(warning this code does not handle
errors, etc.)  I pulled it out of a working unit, but I don't think I left
out any references.  Simply save the task handle from WinExec, and then call
the procedure CloseTask(taskhandle).

-------------begin code-------------
type
  TCallBack = function(hWnd : THandle; lParam : longInt) : boolean;
  PAnswer = ^TAnswer;
  TAnswer = record
    task : THandle;
    hWnd : THandle;
  end;

function EnumWindowsProc(hWnd : THandle; lParam : longInt) : boolean; export;
var
  ans : PAnswer;
  handle : THandle;
begin
  ans := PAnswer(lParam);
  result := true;
  handle := GetWindowWord(hWnd, GWW_HINSTANCE);
  if handle = ans^.task then begin
    ans^.hWnd := hWnd;
    result := false;
  end;
end;

function FindHWnd(task : THandle) : THandle;
var
  callbackptr : ^TCallBack;
  msg : TMsg;
  answer : TAnswer;
begin
  CallBackPtr := MakeProcInstance(@EnumWindowsProc, HInstance);
  answer.task := task;
  answer.hWnd := 0;
  EnumWindows(callBackPtr, longint(@answer));
  result := answer.hWnd;
  FreeProcInstance(CallBackPtr);
end;

procedure CloseTask(task : THandle);
var
  hWnd : THandle;
begin
  hWnd := FindHWnd(FTaskHandle);
  PostMessage(hWnd, wm_quit, 0, 0);
end;
----------end code---------------

Douglas W Sjoquist
Cedarville College
sjoqu...@cedarville.edu
http://www.cedarville.edu/employee/sjoquist/index.htm

Other Threads