cypher175 Posted April 12, 2009 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")..??
Valuater Posted April 12, 2009 Posted April 12, 2009 $PID = Run('C:\Program Files\Internet Explorer\IEXPLORE.EXE "about:blank"') 8)
cypher175 Posted April 12, 2009 Author 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")
Valuater Posted April 12, 2009 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)
Valuater Posted April 12, 2009 Posted April 12, 2009 Or... ShellExecute('IEXPLORE.EXE', "about:blank") WinWaitActive("") $PID = ProcessExists("IEXPLORE.EXE") MsgBox(4096, "Test", $PID 8)
Ascend4nt Posted April 12, 2009 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: Reveal hidden contents 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)
PeterAtkin Posted March 7, 2010 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]
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