Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Terminating a child process - Win32 in Delphi

Posted on 2004-04-29
4
Medium Priority
?
1,228 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 17

Accepted Solution

by:
geobul earned 400 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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

715 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