cypher175 Posted April 12, 2009 Share Posted April 12, 2009 is there anyway that i can get a PID from using this function at all ShellExecute("iexplore.exe", "about:blank")I know you can get a PID from $PID = Run("C:\Program Files\Internet Explorer\IEXPLORE.EXE") but how can you use RUN with IE to open up IE to a Certain page like ("about:blank")..?? Link to comment Share on other sites More sharing options...
Valuater Posted April 12, 2009 Share Posted April 12, 2009 $PID = Run('C:\Program Files\Internet Explorer\IEXPLORE.EXE "about:blank"') 8) Link to comment Share on other sites More sharing options...
cypher175 Posted April 12, 2009 Author Share Posted April 12, 2009 thanx man.. but would there still be anyway at all that i could get a PID from using this function at all though..?? ShellExecute("iexplore.exe", "about:blank") Link to comment Share on other sites More sharing options...
Valuater Posted April 12, 2009 Share Posted April 12, 2009 $PID = Run('C:\Program Files\Internet Explorer\IEXPLORE.EXE "about:blank"') WinWaitActive("") $PID2 = ProcessExists("IEXPLORE.EXE") MsgBox(4096, "Test", $PID & @CRLF & $PID2) 8) Link to comment Share on other sites More sharing options...
Valuater Posted April 12, 2009 Share Posted April 12, 2009 Or... ShellExecute('IEXPLORE.EXE', "about:blank") WinWaitActive("") $PID = ProcessExists("IEXPLORE.EXE") MsgBox(4096, "Test", $PID 8) Link to comment Share on other sites More sharing options...
Ascend4nt Posted April 12, 2009 Share Posted April 12, 2009 The standard WinAPI call *does* return a process handle, with which a process ID can be extracted. Why the AutoIT developers chose not to return a PID I don't know, but it would have proven useful. See the below code, adapted from MrCreatoR's function of the same name -Ascend4nt expandcollapse popup; ================================================================================================= ; Func _ShellExecuteEx($sCmd, $sParams = "", $sFolder = "", $sVerb = "", $iState = @SW_SHOWNORMAL,$bCloseProcessHandle=True) ; ; Parameters are the same as ShellExecute(), except for the addition of: ; ; $bCloseProcessHandle = If True (recommended unless planning on using Process Handles), ; then the Process Handle (if received) is closed ; If False, the Process Handle (if received) is returned - this can be used to do additional work with Processes ; Usage is mostly recommended for the _ShellExecuteExWait() function and/or getting exit code. ; ; Return is different from ShellExecute() in the following way: ; Success: @error = 0, and either the process ID (if $bCloseProcessHandle is True, and process ID received) is returned, ; or a 2-element array (if $bCloseProcessHandle is False): ; $array[0]=Process ID if new process started (and process handle+ID received), ; $array[1]=Process Handle if new process started (and process handle received) ; Failure: @error set and 0 is returned ; @error = 1 = parameters error ; @error = 2 = call failed (probably due to parameter error. can use _WinAPI_GetLastError()) ; ; NOTE: Recommended to run on Windows 2000 or higher because: ; According to Microsoft at http://msdn2.microsoft.com/en-us/library/bb762154.aspx, ; Windows 95/98/Me: ShellExecuteEx is supported by the Microsoft Layer for Unicode (MSLU). ; To use this, you must add certain files to your application, ; as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems. ; So it appears it will break on those machines without MSLU(?) ; ; Initial Code from MrCreatoR on AutoIt Forum Topic:: http://www.autoitscript.com/forum/index.php?showtopic=69868 ; Enhancements/Modifications by: Ascend4nt ; (including process handle/ID extract & close-handle code, plus Unicode/path enhancements, & CoInitializeEx call) ; ================================================================================================= Func _ShellExecuteEx($sCmd, $sParams = "", $sFolder = "", $sVerb = "", $iState = @SW_SHOWNORMAL,$bCloseProcessHandle=True) Local $stINFO,$stVerb,$stPath,$stArgs,$stWDir,$aRet,$hWnd=0,$aProcessArray[2]=[0,0] Local $iParamLen,$iCmdLen,$iFolderLen $iParamLen=StringLen($sParams) ; Verify string lengths are less than maximum. ; Through testing, 1997 (1996+1 NULL-term) is the maximum parameter length for this call (Unicode) If $iParamLen>1996 Then Return SetError(1,0,0) $iCmdLen=StringLen($sCmd) ; Verify string lengths are less than maximum. [MAX_PATH is 260, but Unicode allows exceptions] ; 32767 max length for Unicode strings if prefixed with '\\?\' If $iCmdLen>259 Then ; 32767-NULL=32766 - 4 (\\?\) = 32762 If $iCmdLen>(32766-4) Then Return SetError(1,0,0) $sCmd='\\?\' & $sCmd EndIf $iFolderLen=StringLen($sFolder) ; Verify string lengths are less than maximum. [MAX_PATH is 260, but Unicode allows exceptions] ; 32767 max length for Unicode strings if prefixed with '\\?\' If $iFolderLen>259 Then ; 32767-NULL=32766 - 4 (\\?\) = 32762 If $iFolderLen>(32766-4) Then Return SetError(1,0,0) $sFolder='\\?\' & $sFolder EndIf ; Setup string structures $stVerb = DllStructCreate("wchar["&(StringLen($sVerb)+1)&"]") $stPath = DllStructCreate("wchar[" &($iCmdLen+1)& "];wchar") $stArgs = DllStructCreate("wchar[" &($iParamLen+1)& "];wchar") $stWDir = DllStructCreate("wchar[" &($iFolderLen+1)& "];wchar") ; Initialize string structures (which are then used by pointer in the larger SHELLEXECUTEINFO structure) DllStructSetData($stVerb, 1, $sVerb) DllStructSetData($stPath, 1, $sCmd) DllStructSetData($stWDir, 1, $sFolder) DllStructSetData($stArgs, 1, $sParams) ; SHELLEXECUTEINFO structure $stINFO = DllStructCreate("ulong;ulong;long;ptr;ptr;ptr;ptr;long;long;ptr;ptr;long;ulong;long;long") ; SHELLEXECUTEINFO structure initialize DllStructSetData($stINFO, 1, DllStructGetSize($stINFO)) ; cbSize, size (in bytes) of structure ; ------------------------------------------------------------------------------------------------------ ; fMask Options: ; 0x40 = SEE_MASK_NOCLOSEPROCESS. The 15th element in structure (hProcess) will be set with the Process handle ; NOTE: per MSDN, this handle *must* be closed by the caller. (similar to how "OpenProcess" must use "CloseProcess") ; 0x400 = SEE_MASK_FLAG_NO_UI = Do not display an error message box if an error occurs. ; This is not default ShellExecute() behavior, which will display the error message box ; ------------------------------------------------------------------------------------------------------ DllStructSetData($stINFO, 2, BitOR(0x40,0x400)) ; fMask ; HWND - MSDN: A window handle to any message boxes that the system might produce while executing this function. DllStructSetData($stINFO, 3, $hWnd) ; Is this supposed to *receive* instead of send? I have yet to get clarity on this. DllStructSetData($stINFO, 4, DllStructGetPtr($stVerb)) ; lpVerb: pointer to the verb string DllStructSetData($stINFO, 5, DllStructGetPtr($stPath)) ; lpFile: pointer to the $cmd string DllStructSetData($stINFO, 6, DllStructGetPtr($stArgs)) ; lpParameters: pointer to the parameters/arguments string DllStructSetData($stINFO, 7, DllStructGetPtr($stWDir)) ; lpDirectory: pointer to working directory string DllStructSetData($stINFO, 8, $iState) ; nShow = state to show window as #cs ; ------------------------------------------------------------------------------------------------------ ; Per MSDN Documentation, the following call should be done prior to calling ShellExecuteEx: ; CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE) ; COINIT_APARTMENTTHREADED = 0x2,COINIT_DISABLE_OLE1DDE = 0x4 ; Reason: ; "Because ShellExecuteEx can delegate execution to Shell extensions (data sources, context menu handlers, verb implementations) ; that are activated using Component Object Model (COM), COM should be initialized before ShellExecuteEx is called. ; Some Shell extensions require the COM single-threaded apartment (STA) type. In that case, COM should be initialized as shown here. ; There are certainly instances where ShellExecuteEx does not use one of these types of Shell extension and those instances would not ; require COM to be initialized at all. Nonetheless, it is good practice to always initalize COM before using this function." ; ------------------------------------------------------------------------------------------------------ #ce DllCall("ole32.dll", "int", "CoInitializeEx", "ptr", Chr(0), "dword", BitOR(2,4)) ; I don't care if it succeeds. Doesn't seem to make much difference even to call it. $aRet=DllCall("shell32.dll", "int", "ShellExecuteExW", "ptr", DllStructGetPtr($stINFO)) If @error Or Not $aRet[0] Then ; DLLStructDelete()'s: $stINFO=0 $stVerb=0 $stPath=0 $stArgs=0 $stWDir=0 Return SetError(2,@error,0) EndIf ; Get Process Handle, if one exists (non-NULL if new process started, otherwise ; NULL if app that performs 'verb' is already running, or is perhaps a 'properties' dialog etc) $aProcessArray[1]=DllStructGetData($stINFO,15) ; Get Process ID from Handle If ($aProcessArray[1]) Then $aRet=DllCall("Kernel32.dll","dword","GetProcessId","long",$aProcessArray[1]) If IsArray($aRet) Then $aProcessArray[0]=$aRet[0] EndIf ;ConsoleWrite("Handle passed to function:" & Number($hWnd) & ", Handle AFTER call:" & Number(DllStructGetData($stINFO,3)) & @CRLF) ;ConsoleWrite("Process Handle:" & Number($hProcess) & ", Process ID:" & Number($vProcessID) & @CRLF) ; Close Handle If $bCloseProcessHandle And $aProcessArray[1] Then DllCall('kernel32.dll','ptr', 'CloseHandle','ptr', $aProcessArray[1]) ; DLLStructDelete()'s: $stINFO=0 $stVerb=0 $stPath=0 $stArgs=0 $stWDir=0 If ($bCloseProcessHandle) Then Return SetError(0,0,$aProcessArray[0]) SetError(0,0) Return $aProcessArray EndFunc My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs |Â Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) |Â Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
PeterAtkin Posted March 7, 2010 Share Posted March 7, 2010 (edited) How can one use this, is it possible to have an example? I have done this so far but... expandcollapse popup#include <EventLog.au3> #include <Array.au3> Global $KillApp[4] $KillApp[1] = "skype.exe" $KillApp[2] = "skypePM.exe" $KillApp[3] = "skypenames2.exe" kill_before_application() $PID = _ShellExecuteEx("desk.cpl", @SystemDir & "\") Sleep(1000) run_application("StarCraft.exe", @WorkingDir & "\") ProcessClose($PID) Func kill_before_application() For $i = 1 To $KillApp[0] Step 1 If ProcessExists($KillApp[$i]) Then ProcessClose($KillApp[$i]) If @error Then _put_event(1, "Application :" & $KillApp[$i] & " not terminated", @error) Else _put_event(4, "Application :" & $KillApp[$i] & " terminated", @error) EndIf EndIf Next EndFunc ;==>kill_before_application Func kill_after_application($PID1) If ProcessExists($PID1) Then ProcessClose($PID1) If @error Then _put_event(1, "process :" & $PID1 & " not terminated", @error) Else _put_event(4, "process :" & $PID1 & " terminated", @error) EndIf EndIf EndFunc ;==>kill_after_application Func start_application($process) If Not ProcessExists($process) Then Run($process) EndFunc ;==>start_application Func run_application($application, $directory) Local $val = RunWait($application, $directory, @SW_MAXIMIZE) If @error Then _put_event(1, "Application :" & $application & " not started exit code :" & $val, @error) Else _put_event(4, "Application :" & $application & " stared", @error) EndIf EndFunc ;==>run_application Func _put_event($value, $text, $error_id_code) ;SUCCESS = 0 ;ERROR =1 ;WARNING =2 ;INFORMATION =4 ;AUDIT_SUCCESS =8 ;AUDIT_FAILURE =16 Local $hEventLog, $aData[4] = [3, 1, 2, 3] $hEventLog = _EventLog__Open("", "StarCraft Loader") _EventLog__Report($hEventLog, $value, 0, $error_id_code, @UserName, @CRLF & $text, $aData) _EventLog__Close($hEventLog) EndFunc ;==>_put_event ; ================================================================================================= ; Func _ShellExecuteEx($sCmd, $sParams = "", $sFolder = "", $sVerb = "", $iState = @SW_SHOWNORMAL,$bCloseProcessHandle=True) ; ; Parameters are the same as ShellExecute(), except for the addition of: ; ; $bCloseProcessHandle = If True (recommended unless planning on using Process Handles), ; then the Process Handle (if received) is closed ; If False, the Process Handle (if received) is returned - this can be used to do additional work with Processes ; Usage is mostly recommended for the _ShellExecuteExWait() function and/or getting exit code. ; ; Return is different from ShellExecute() in the following way: ; Success: @error = 0, and either the process ID (if $bCloseProcessHandle is True, and process ID received) is returned, ; or a 2-element array (if $bCloseProcessHandle is False): ; $array[0]=Process ID if new process started (and process handle+ID received), ; $array[1]=Process Handle if new process started (and process handle received) ; Failure: @error set and 0 is returned ; @error = 1 = parameters error ; @error = 2 = call failed (probably due to parameter error. can use _WinAPI_GetLastError()) ; ; NOTE: Recommended to run on Windows 2000 or higher because: ; According to Microsoft at [url="http://msdn2.microsoft.com/en-us/library/bb762154.aspx"]http://msdn2.microsoft.com/en-us/library/bb762154.aspx[/url], ; Windows 95/98/Me: ShellExecuteEx is supported by the Microsoft Layer for Unicode (MSLU). ; To use this, you must add certain files to your application, ; as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems. ; So it appears it will break on those machines without MSLU(?) ; ; Initial Code from MrCreatoR on AutoIt Forum Topic:: [url="http://www.autoitscript.com/forum/index.php?showtopic=69868"]http://www.autoitscript.com/forum/index.php?showtopic=69868[/url] ; Enhancements/Modifications by: Ascend4nt ; (including process handle/ID extract & close-handle code, plus Unicode/path enhancements, & CoInitializeEx call) ; ================================================================================================= Func _ShellExecuteEx($sCmd, $sParams = "", $sFolder = "", $sVerb = "", $iState = @SW_SHOWNORMAL, $bCloseProcessHandle = True) Local $stINFO, $stVerb, $stPath, $stArgs, $stWDir, $aRet, $hWnd = 0, $aProcessArray[2] = [0, 0] Local $iParamLen, $iCmdLen, $iFolderLen $iParamLen = StringLen($sParams) ; Verify string lengths are less than maximum. ; Through testing, 1997 (1996+1 NULL-term) is the maximum parameter length for this call (Unicode) If $iParamLen > 1996 Then Return SetError(1, 0, 0) $iCmdLen = StringLen($sCmd) ; Verify string lengths are less than maximum. [MAX_PATH is 260, but Unicode allows exceptions] ; 32767 max length for Unicode strings if prefixed with '\\?\' If $iCmdLen > 259 Then ; 32767-NULL=32766 - 4 ([url="file://\?"]\\?\[/url]) = 32762 If $iCmdLen > (32766 - 4) Then Return SetError(1, 0, 0) $sCmd = '\\?\' & $sCmd EndIf $iFolderLen = StringLen($sFolder) ; Verify string lengths are less than maximum. [MAX_PATH is 260, but Unicode allows exceptions] ; 32767 max length for Unicode strings if prefixed with '\\?\' If $iFolderLen > 259 Then ; 32767-NULL=32766 - 4 ([url="file://\?"]\\?\[/url]) = 32762 If $iFolderLen > (32766 - 4) Then Return SetError(1, 0, 0) $sFolder = '\\?\' & $sFolder EndIf ; Setup string structures $stVerb = DllStructCreate("wchar[" & (StringLen($sVerb) + 1) & "]") $stPath = DllStructCreate("wchar[" & ($iCmdLen + 1) & "];wchar") $stArgs = DllStructCreate("wchar[" & ($iParamLen + 1) & "];wchar") $stWDir = DllStructCreate("wchar[" & ($iFolderLen + 1) & "];wchar") ; Initialize string structures (which are then used by pointer in the larger SHELLEXECUTEINFO structure) DllStructSetData($stVerb, 1, $sVerb) DllStructSetData($stPath, 1, $sCmd) DllStructSetData($stWDir, 1, $sFolder) DllStructSetData($stArgs, 1, $sParams) ; SHELLEXECUTEINFO structure $stINFO = DllStructCreate("ulong;ulong;long;ptr;ptr;ptr;ptr;long;long;ptr;ptr;long;ulong;long;long") ; SHELLEXECUTEINFO structure initialize DllStructSetData($stINFO, 1, DllStructGetSize($stINFO)) ; cbSize, size (in bytes) of structure ; ------------------------------------------------------------------------------------------------------ ; fMask Options: ; 0x40 = SEE_MASK_NOCLOSEPROCESS. The 15th element in structure (hProcess) will be set with the Process handle ; NOTE: per MSDN, this handle *must* be closed by the caller. (similar to how "OpenProcess" must use "CloseProcess") ; 0x400 = SEE_MASK_FLAG_NO_UI = Do not display an error message box if an error occurs. ; This is not default ShellExecute() behavior, which will display the error message box ; ------------------------------------------------------------------------------------------------------ DllStructSetData($stINFO, 2, BitOR(0x40, 0x400)) ; fMask ; HWND - MSDN: A window handle to any message boxes that the system might produce while executing this function. DllStructSetData($stINFO, 3, $hWnd) ; Is this supposed to *receive* instead of send? I have yet to get clarity on this. DllStructSetData($stINFO, 4, DllStructGetPtr($stVerb)) ; lpVerb: pointer to the verb string DllStructSetData($stINFO, 5, DllStructGetPtr($stPath)) ; lpFile: pointer to the $cmd string DllStructSetData($stINFO, 6, DllStructGetPtr($stArgs)) ; lpParameters: pointer to the parameters/arguments string DllStructSetData($stINFO, 7, DllStructGetPtr($stWDir)) ; lpDirectory: pointer to working directory string DllStructSetData($stINFO, 8, $iState) ; nShow = state to show window as #cs ; ------------------------------------------------------------------------------------------------------ ; Per MSDN Documentation, the following call should be done prior to calling ShellExecuteEx: ; CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE) ; COINIT_APARTMENTTHREADED = 0x2,COINIT_DISABLE_OLE1DDE = 0x4 ; Reason: ; "Because ShellExecuteEx can delegate execution to Shell extensions (data sources, context menu handlers, verb implementations) ; that are activated using Component Object Model (COM), COM should be initialized before ShellExecuteEx is called. ; Some Shell extensions require the COM single-threaded apartment (STA) type. In that case, COM should be initialized as shown here. ; There are certainly instances where ShellExecuteEx does not use one of these types of Shell extension and those instances would not ; require COM to be initialized at all. Nonetheless, it is good practice to always initalize COM before using this function." ; ------------------------------------------------------------------------------------------------------ #ce DllCall("ole32.dll", "int", "CoInitializeEx", "ptr", Chr(0), "dword", BitOR(2, 4)) ; I don't care if it succeeds. Doesn't seem to make much difference even to call it. $aRet = DllCall("shell32.dll", "int", "ShellExecuteExW", "ptr", DllStructGetPtr($stINFO)) If @error Or Not $aRet[0] Then ; DLLStructDelete()'s: $stINFO = 0 $stVerb = 0 $stPath = 0 $stArgs = 0 $stWDir = 0 Return SetError(2, @error, 0) EndIf ; Get Process Handle, if one exists (non-NULL if new process started, otherwise ; NULL if app that performs 'verb' is already running, or is perhaps a 'properties' dialog etc) $aProcessArray[1] = DllStructGetData($stINFO, 15) ; Get Process ID from Handle If ($aProcessArray[1]) Then $aRet = DllCall("Kernel32.dll", "dword", "GetProcessId", "long", $aProcessArray[1]) If IsArray($aRet) Then $aProcessArray[0] = $aRet[0] EndIf ;ConsoleWrite("Handle passed to function:" & Number($hWnd) & ", Handle AFTER call:" & Number(DllStructGetData($stINFO,3)) & @CRLF) ;ConsoleWrite("Process Handle:" & Number($hProcess) & ", Process ID:" & Number($vProcessID) & @CRLF) ; Close Handle If $bCloseProcessHandle And $aProcessArray[1] Then DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $aProcessArray[1]) ; DLLStructDelete()'s: $stINFO = 0 $stVerb = 0 $stPath = 0 $stArgs = 0 $stWDir = 0 If ($bCloseProcessHandle) Then Return SetError(0, 0, $aProcessArray[0]) SetError(0, 0) Return $aProcessArray EndFunc ;==>_ShellExecuteEx ; T.D.L ; Need to find a way to close tyhe desk.cpl process ; way to automatically make sure that the application compatibility properties are all ticked But still cannot close the process, when I run sysinternal Process Explorer and look for the number that your system generates it cannot be found, but the process is stll clearly running? am i doing anything wrong.. Edited March 7, 2010 by PeterAtkin [topic='115020'] AD Domain Logon Script[/topic] Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now