Solved

Terminating a child process - Win32 in Delphi

Posted on 2004-04-29
4
1,152 Views
Last Modified: 2012-06-21
I have spawned a child process using CreateProcess and want to
terminate it politely i.e. not by using TerminateProcess which is
draconian.  I had thought of sending a WM_CLOSE message.  However, the
handle to the process (from ProcessInfo.hProcess) is not the same as
the app handle I need nor the handle of the spawned app's main form.

Does anybody know either
a) how I can get the appropriate handle
b) a better way of politely terminating the process than sending a
WM_CLOSE message.

The precise executable spawned is not known at designtime so I can't
look for the window by name.

Cheers.
0
Comment
Question by:Ency
  • 2
  • 2
4 Comments
 
LVL 17

Accepted Solution

by:
geobul earned 100 total points
ID: 10948370
Hi,

var
  TargetHWND: HWND;
  TargetProcID: cardinal;

function EnumerateWindows(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
var ProcessId: cardinal;
begin
  GetWindowThreadProcessId(hWnd,@ProcessId);
  if ProcessID = TargetProcID then begin
    TargetHWND := hWnd;
    result := false; // stop enumeration
  end else
    result := true; // continue enumeration
end;

// usage:
TargetHWND := 0;
TargetProcID := ...; //your value here
EnumWindows(@EnumerateWindows, 0); // enumerate all top-level windows
if TargetHWND <> 0 then begin
  SendMessage(TargetHWND, WM_CLOSE, 0, 0);
end;

Regards, Geo
0
 

Author Comment

by:Ency
ID: 10949927
Thanks for that.  However it does not seem to work.  Here's what I'm getting:

Firstly, the call back is working and is picking up (among many others) the main window of my spawned process.  
I know this because I've made API calls GetClassName and GetWindowText with the enumerated windows handles.  

The problem is that the process and thread IDs passed back by GetWindowThreadProcessId are different to the
Handle I get returned by CreateProcess in TProcessInformation.  I can only assume that a process or thread's ID is
not the same thing as its handle.

Have I misunderstood something?  If not is there some way of getting the process or thread ID from the handle
or vice versa?

For what it's worth the code that demonstrates this problem is below.
=========================================================================

var
  Target: TListView;

function EnumerateWindows(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
var
  ProcessId: cardinal;
  ThreadID: cardinal;
  lpString: PChar;
  ListItem: TlistItem;
begin
  lpString := StrAlloc(256);
  try
    ListItem := Target.Items.Add;
    GetClassName(hWnd,lpString,255);
    ListItem.Caption := lpString;
    GetWindowText(hWnd,lpString,255);
    ListItem.SubItems.Add( lpString );
    ThreadId := GetWindowThreadProcessId(hWnd,@ProcessId);
    ListItem.SubItems.Add( IntToSTr(ProcessId) );
    ListItem.SubItems.Add( IntToStr(ThreadId) );
    Result := True;
  finally
    StrDispose(lpString);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ListView1.Items.BeginUpdate;
  try
    Target := ListView1;
    ListView1.Items.Clear;
    EnumWindows(@EnumerateWindows,0);
  finally
    ListView1.Items.EndUpdate;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ProcessInfo: TProcessInformation;
  StartupInfo: TStartupInfo;
begin
  { Null these records }
  FillChar( StartupInfo, SizeOf(StartupInfo), 0 );
  FillChar( ProcessInfo, SizeOf(ProcessInfo), 0 );

  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_SHOWNORMAL;

  if not CreateProcess( nil, PChar('c:\test\project1.exe'), nil, nil, False, NORMAL_PRIORITY_CLASS,
    nil, PChar('c:\test'), StartupInfo, ProcessInfo ) then
    raise Exception.Create( 'CreateProcess Failed' );

  label1.Caption := IntToStr(ProcessInfo.hProcess);
  label2.Caption := IntToStr(ProcessInfo.hThread);
end;


0
 

Author Comment

by:Ency
ID: 10950113
Doh!

<sheepish>
I've just realised that TProcessInfo has members dwProcessId and dwThreadId.  I feel pretty silly now.
</sheepish>

Oh well I supose if you have to make a fool of yourself there's nothing quite like doing it on the internet.
0
 
LVL 17

Expert Comment

by:geobul
ID: 10950313
Oh, I'm sorry. I really forgot to say where you should get the TargetProcID from. Glad you've managed it yourself.

Thanks for the grade :-)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Activex loadlibrary and show parented form issue 6 286
Run video youtube webbrowse 10 57
control image tags in a string ? 12 111
Delphi...Split view - idea? 1 42
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

895 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now