?
Solved

PostMessage to process

Posted on 2003-02-27
5
Medium Priority
?
1,431 Views
Last Modified: 2007-12-19
Hi, Im trying to figure out how I can stop a process started with the following code:

function WinExecAndWait32(FileName:String; Visibility : integer):integer;
var
 zAppName:array[0..512] of char;
 zCurDir:array[0..255] of char;
 WorkDir:String;
 StartupInfo:TStartupInfo;
 ProcessInfo:TProcessInformation;
begin
 StrPCopy(zAppName,FileName);
 GetDir(0,WorkDir);
 StrPCopy(zCurDir,WorkDir);
 FillChar(StartupInfo,Sizeof(StartupInfo),#0);
 StartupInfo.cb := Sizeof(StartupInfo);

 StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
 StartupInfo.wShowWindow := Visibility;
 if not CreateProcess(nil,
   zAppName,                      { pointer to command line string }
   nil,                           { pointer to process security attributes }
   nil,                           { pointer to thread security attributes }
   false,                         { handle inheritance flag }
   CREATE_NEW_CONSOLE or          { creation flags }
   NORMAL_PRIORITY_CLASS,
   nil,                           { pointer to new environment block }
   nil,                           { pointer to current directory name }
   StartupInfo,                   { pointer to STARTUPINFO }
   ProcessInfo) then Result := -1 { pointer to PROCESS_INF }

 else begin
---->   PostThreadMessage(ProcessInfo.hThread, WM_QUIT, 0, 0); { I tried this, but no go }
   WaitforSingleObject(ProcessInfo.hProcess,INFINITE);
   MainForm.Win32ExecHandle := -1;
   Result := SUCCESS;
 end;
end;


I want another thread to be able to stop the process. I assume posting a WM_QUIT message would be the nicest way to do it (I'd prefer not to use TerminateProcess). But the question is, which handle should I post to? As you can see above I post a quit message right before I wait for the process to end. But it never ends. Im testing this by executing notepad, which shows up but never stops unless I close it manually.
0
Comment
Question by:pede
[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
5 Comments
 
LVL 26

Expert Comment

by:Russell Libby
ID: 8035945

The PostThreadMessage expects a thread id, not a thread handle, which is what you are passing. Try using the dwThreadId from the ProcessInfo. Also capture the return value of PostThreadMessage so you can determine if you should call GetLastError (to find out what went wrong)

Russell

0
 
LVL 1

Expert Comment

by:Pandora
ID: 8037823
listening...
0
 
LVL 1

Author Comment

by:pede
ID: 8040693
I forgot to mention it, but I already tried with dwThreadId, which didnt work either. I got invalid thread identifier in both cases.

But! I just discovered something interesting:

This fails:

   if not PostThreadMessage(ProcessInfo.dwThreadId, WM_QUIT, 0, 0) then begin
    MessageBox(0, pchar(SysErrorMessage(GetLastError)), 'LastError', MB_ICONERROR);
   end;
   WaitforSingleObject(ProcessInfo.hProcess,INFINITE);


This works:

   Sleep(2000);
   if not PostThreadMessage(ProcessInfo.dwThreadId, WM_QUIT, 0, 0) then begin
    MessageBox(0, pchar(SysErrorMessage(GetLastError)), 'LastError', MB_ICONERROR);
   end;
   WaitforSingleObject(ProcessInfo.hProcess,INFINITE);

Looks like the main thread isnt initialized when CreateProcess returns (please correct me if Im mistaken). The reason I try to quit at once is just that I thought it was the easiest way to test if it worked or not. I just want the ability to abort it, so unless I try to abort a split second after CreateProcess it will be fine. This could happen though, even if very unlikely. Is there a function that can wait until the main thread is created for sure?

Regards,
Pede
0
 
LVL 26

Accepted Solution

by:
Russell Libby earned 200 total points
ID: 8041916

Pede,
Yes, you could use WaitForInputIdle:

The WaitForInputIdle function waits until the given process is waiting for user input with no input pending, or until the time-out interval has elapsed.

The WaitForInputIdle function only works with GUI applications. If a console application calls the function, it returns immediately, with no wait.

DWORD WaitForInputIdle(

    HANDLE hProcess,     // handle to process
    DWORD dwMilliseconds      // time-out interval in milliseconds  
    );    
 

Parameters

hProcess

Identifies the process.

dwMilliseconds

Specifies the time-out interval, in milliseconds. If dwMilliseconds is INFINITE, the function does not return until the process is idle.

Remarks

The WaitForInputIdle function enables a thread to suspend its execution until a specified process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronizing a parent process and a newly created child process. When a parent process creates a child process, the CreateProcess function returns without waiting for the child process to finish its initialization. Before trying to communicate with the child process, the parent process can use WaitForInputIdle to determine when the child's initialization has been completed. For example, the parent process should use WaitForInputIdle before trying to find a window associated with the child process. Remarks

-------------

Hope this does what you want it to,
Russell

0
 
LVL 1

Author Comment

by:pede
ID: 8041961
Looks good, thanks
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses
Course of the Month7 days, 21 hours left to enroll

765 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