Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Kill a process
Message
 
À
29/03/2004 16:31:25
Information générale
Forum:
Visual FoxPro
Catégorie:
Fonctions Windows API
Titre:
Divers
Thread ID:
00890217
Message ID:
00890842
Vues:
22
>>>Ooopss sorry. I didn't looked into the code I have <*g*>
>>>You right. This is mine:
>>>
>>>   Declare Long GetExitCodeProcess in Kernel32 ;
>>>      Long hProcess, Long @nExitCode
>>>
>>>   ll_Error = (GetExitCodeProcess(ln_hProcess, @ln_ExitCode) == 0)
>>>   If !ll_Error and (ln_ExitCode != 259)
>>>      *** Do something
>>>   endif
>>>
>>>
>>>Btw, I have looked into your code. I don't think it will wait if Acrobat is already running. Have you try that ?
>>
>>Yes, Herman, I realized that Tracy's code wouldn't work if Acrobat were already running, as I mentioned in Re: ShellExecute WaitForSingleObject IsRunning(GeorgeTasker) Thread #887963 Message #888036. The issue I was addressing had to do with a flakyness in WaitForSingleObject, even without the complication of a prior instance of Acrobat. For some unknown reason, WaitForSingleObject left Acrobat process residue, but this was circumvented by substituting an essentially equivalent (I thought) piece of code that uses GetExitCodeProcess.
>>
>>Mike
>
>I see. The reason is because it was use an INFINITE for the WaitForSingleObject parameter. The behavior is well documented in MSDN. If something happen to the process (i.e.: self terminated, such as Acrobat & MS Outlook), INFINITE can cause a system deadlocked. It is better (recommended) to use a timeout. Then use GetExitCodeProcess to check what is the exit code. If exit code is 0 then it is closed properly. Usually for self terminated process it returns -1.
>
>Here is part of my code:
>
>#Define STILL_ACTIVE    0x103
>#Define STATUS_TIMEOUT  0x0102
>#Define WAIT_TIMEOUT    STATUS_TIMEOUT
>#Define WAIT_OBJECT_0   0
>#Define SYNCHRONIZE     0x100000
>
>Declare Long WaitForInputIdle in User32 ;
>   Long hProcess, Long dwMilliseconds
>Declare Long GetWindowThreadProcessId in User32 ;
>   Long nhWnd, Long @lpdwProcessId
>Declare Long OpenProcess in Kernel32 ;
>   Long dwDesiredAccess, Long bInheritHandle, Long dwProcessId
>
>ln_Return = CreateProcess(...)
>ln_hProcess = ...
>ln_hThread = ...
>
>WaitForInputIdle( ln_hProcess, WAIT_TIMEOUT )
>ln_ExitCode = STILL_ACTIVE
>ll_Error = .F.
>Do while ((ln_Return != WAIT_OBJECT_0) or (ln_ExitCode == STILL_ACTIVE)) and !ll_Error
>   ln_Return = WaitForSingleObject(ln_hProcess, int(WAIT_TIMEOUT/3))
>   If (ln_Return == WAIT_OBJECT_0)
>      ll_Error = (GetExitCodeProcess(ln_hProcess, @ln_ExitCode) == 0)
>      If ll_Error
>         ? 'Error: ', GetLastError()
>      endif
>   endif
>
>   If (ln_Return == WAIT_OBJECT_0) and (ln_ExitCode == -1) and !ll_Error
>      ** The process doesn't exit properly (probably killed / self terminated)
>      ** Close the handle first
>      CloseHandle( ln_hProcess )
>      CloseHandle( ln_hThread )
>      Store 0 to ln_hProcess, ln_hThread
>
>      ** Search for the document we are trying to open
>      lc_PDF = 'Acrobat Reader - [test.pdf]'
>      ln_hWnd = FindWindow( Null, lc_PDF )
>      If (ln_hWnd != 0)
>         ** It is opened by another process
>         ** Get the process handle and start the loop again
>         ln_ProcessId = 0
>         GetWindowThreadProcessId( ln_hWnd, @ln_ProcessId )
>         ln_hProcess = OpenProcess( SYNCHRONIZE, 0, ln_ProcessId )
>         If (ln_hProcess != 0)
>            ln_Return = STATUS_TIMEOUT
>         endif
>      endif
>   endif
>enddo
>
>If (ln_hProcess != 0)
>   CloseHandle( ln_hProcess )
>endif
>If (ln_hThread != 0)
>   CloseHandle( ln_hThread )
>endif
>
>
>BTW, is it ok to use this thread for this ?

Thanks for clearing up the mystery about WaitForInputIdle. Yes, we've drifted off thread, but while we're on the subject, note that explorer.exe uses an exitcode of 1 when it passes control to another instance, and the most common (and useless) value of exitcode in such situations is 0 (e.g. for Word, Outlook Express, Spy++, Wordpad, etc.). I guess it really depends on your application and programming conventions what you would want to do when the process already exists, as opposed to having truly been created by your own program. In most cases, the pass-off automatically activates the pre-existing window, so there may be no need to do anything more, as far as capturing its HWND and/or processid.

Mike
Montage

"Free at last..."
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform