Jump to content

ProcessExists not detect all processes


Recommended Posts

Hello, I made a script to run an app, save the processID and while it is running do something, but when the process is no longer running it exits t he "while" and do a processclose and shutdown:

local $iPID = Run($CmdLine[1], "", @SW_SHOWMAXIMIZED)

Sleep(5000)

While ProcessExists($iPID)
      <DO SOMETHING>
    Sleep(1000)
WEnd

ProcessClose($iPID)
Shutdown(20)
Run(@ComSpec & " /c " & 'tsdiscon', "", @SW_HIDE)
exit

 

The script works very well, but only for "new apps": it works with Chrome, Notepad, Paint, Wordpad, all Office suite, Openoffice, but running Internet Explorer, Calculator and other "older" apps, the script exits the "while" immediately, going to ProcessClose and Shutdown.

There is some different to run e take processID for older apps?

Sorry for my english

 

Link to post
Share on other sites

There are a number of applications ("new" and "old") that starts the application under a PID but changes PID just instants after (by running a secondary exe).  The original PID is simply closed.  This is why your While Loop ends prematurely.  You will need to check for that new PID on those apps.

BTW, why do you ProcessClose an application that does not exist anymore ? :huh2:

Link to post
Share on other sites
Link to post
Share on other sites

I made this and it works 

Run("C:\Program Files\Internet Explorer\iexplore.exe", "", @SW_SHOWMAXIMIZED)
WinWaitActive("[CLASS:IEFrame]", "")
Local $iPid = WinGetProcess("[CLASS:IEFrame]", "")

but I need to get the CLASS from the run function, because I need to use the cmdline[1] to run different apps instead of the specific .exe:

 

Run($CmdLine[1], "", @SW_SHOWMAXIMIZED)
WinWaitActive("[CLASS:<HowGetClassFromRun>]", "")
Local $iPid = WinGetProcess("[CLASS:<HowGetClassFromRun>]", "")

 

Edited by VirusAlert
added code
Link to post
Share on other sites

One simple solution. Just make an ini file containing the .exe and its class name.  You are not running thousands of apps, do you ? 

Link to post
Share on other sites

First thing I can add is that you should probably put in some kinda check to see if the run call was successful.   If it fails put in a backup plan.

This returns all running processes.   It's possible a program could use a process just to startup and hand control off to another.  Meaning the original would close.  

https://www.autoitscript.com/autoit3/docs/functions/ProcessList.htm

 

If you're using a command line to execute the process you could also try using _winapi_createprocess().

Last thing is if your while loop is exited wouldn't that indicate that the process was closed? Hence no need to close it after the fact...just a thought. 

Link to post
Share on other sites

this seems messy but checks all the boxes.  worked just fine when I tested it, I didn't use a command line to launch it. I just replaced $cmdline with null and put the target app name in the first parameter. it launched the exe and spit out the pid.  

 

#include <WinAPI.au3>

$cmdline="place holder"

;~ typedef struct _STARTUPINFOA {
;~   DWORD  cb;
;~   LPSTR  lpReserved;
;~   LPSTR  lpDesktop;
;~   LPSTR  lpTitle;
;~   DWORD  dwX;
;~   DWORD  dwY;
;~   DWORD  dwXSize;
;~   DWORD  dwYSize;
;~   DWORD  dwXCountChars;
;~   DWORD  dwYCountChars;
;~   DWORD  dwFillAttribute;
;~   DWORD  dwFlags;
;~   WORD   wShowWindow;
;~   WORD   cbReserved2;
;~   LPBYTE lpReserved2;
;~   HANDLE hStdInput;
;~   HANDLE hStdOutput;
;~   HANDLE hStdError;
;~ } STARTUPINFOA, *LPSTARTUPINFOA;

$si=DllStructCreate("struct;dword;ptr;ptr;dword;dword;dword;dword;dword;dword;dword;dword;word;word;ptr;handle;handle;handle;endstruct")

    DllStructSetData($si,1,DllStructGetSize($si))

;~ typedef struct _PROCESS_INFORMATION {
;~     HANDLE hProcess;
;~     HANDLE hThread;
;~     DWORD dwProcessId;
;~     DWORD dwThreadId;
;~ } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;

$pi=DllStructCreate("struct;handle;handle;dword;dword;endstruct")


;~ CreateProcessA(
;~     _In_opt_ LPCSTR lpApplicationName,
;~     _Inout_opt_ LPSTR lpCommandLine,
;~     _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
;~     _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
;~     _In_ BOOL bInheritHandles,
;~     _In_ DWORD dwCreationFlags,
;~     _In_opt_ LPVOID lpEnvironment,
;~     _In_opt_ LPCSTR lpCurrentDirectory,
;~     _In_ LPSTARTUPINFOA lpStartupInfo,
;~     _Out_ LPPROCESS_INFORMATION lpProcessInformation
;~     );


if not _WinAPI_CreateProcess(Null,$cmdline,Null,Null,false,0,Null,Null,DllStructGetPtr($si),DllStructGetPtr($pi)) then ConsoleWrite("error code = " & _WinAPI_GetLastError())

$pid=DllStructGetData($pi,3)

MsgBox('','',$pid)

_WinAPI_CloseHandle(DllStructGetData($pi,1))

_WinAPI_CloseHandle(DllStructGetData($pi,2))

 

Edited by markyrocks
Link to post
Share on other sites

Thanks a lot at all of you, i solved using this:

Run($CmdLine[1], "", @SW_SHOWMAXIMIZED)
Select
   Case StringInStr($CmdLine[1], "iexplore")
      $classe = "IEFrame"
   Case StringInStr($CmdLine[1], "explorer")
      $classe = "CabinetWClass"
   Case Else
      Exit
EndSelect
      
WinWaitActive("[CLASS:" & $classe & "]", "")
Local $iPid = WinGetProcess("[CLASS:" & $classe & "]", "")

While WinExists("[CLASS:" & $classe & "]", "")

and it work very well.

Thanks again

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...