Sars! Posted September 25, 2007 Share Posted September 25, 2007 Hey guys, I took my favourite memory searcher (T-search) and went to look for the ammount of memory a certain program uses. I opened taskmanager, and looked for the value. For some reason I didn't find any adress for the value. The program I want to create: I want the program to detect the memory usage of a certain process, and as soon as the value changes do an action. As soon as the value stays constant, I want it to do another action. Looking forward for help Grtz, Sars! Link to comment Share on other sites More sharing options...
Arterie Posted September 25, 2007 Share Posted September 25, 2007 I am not the best with autoit but i thin kthis what you want to do is a lot easier in c++. a friend of mine told me so and he already did nearly the same. Link to comment Share on other sites More sharing options...
Sars! Posted September 25, 2007 Author Share Posted September 25, 2007 BUMP? I don't know enough of c++ Thx in advance, Sars! Link to comment Share on other sites More sharing options...
Nutster Posted September 25, 2007 Share Posted September 25, 2007 Try looking at the Process... functions in the help file. I have not worked with them that much, but they should do the job for you. David NuttallNuttall Computer Consulting An Aquarius born during the Age of Aquarius AutoIt allows me to re-invent the wheel so much faster. I'm off to write a wizard, a wonderful wizard of odd... Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 25, 2007 Share Posted September 25, 2007 (edited) BUMP?I don't know enough of c++ Thx in advance,Sars!Is this an AutoIt question? Because this is an AutoIt forum... Edit: If it is an AutoIt solution you were looking for, I haven't found it yet. I did a UDF called _ProcessListProperties(), but never figured out how to get per-process memory usage for it. I understand it can be done with third-party .exe or .dll files (weaponx mentioned one, I believe), but I'm hoping to find a way with just AutoIt and the existing Windows environment. Edited September 25, 2007 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Sars! Posted September 25, 2007 Author Share Posted September 25, 2007 (edited) Well I'm aiming for it to be done through autoit... Alternatives that are possible are welcome too Grtz, Sars! I also found this: _API_GlobalMemStatus $aMem[0] - Percent of Mem in use $aMem[1] - Physical Mem: Total $aMem[2] - Physical Mem: Free $aMem[3] - Paging file: Total $aMem[4] - Paging file: Free $aMem[5] - User Mem: Total $aMem[6] - User Mem: Free But won't give a specific process information... Grtz, Sars! Edited September 25, 2007 by Sars! Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 26, 2007 Share Posted September 26, 2007 Well I'm aiming for it to be done through autoit...Alternatives that are possible are welcome too Grtz,Sars!I also found this:_API_GlobalMemStatusBut won't give a specific process information...That's part of PaulIA's excellent Auto3Lib AutoIt Library, and very similar to the native MemGetStats(). But, as you say, neither gives info on a single process.This looks like it might do it: GetProcessMemoryInfo FunctionUses PSAPI.dll which comes with Windows (NT and above at least), but I don't know enough about DLLs yet to figure out the call from AutoIt. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
therks Posted September 26, 2007 Share Posted September 26, 2007 Have a look at the Computer Info UDF's made by JSThePatriot. Specifically the _ComputerGetProcesses function. I use it in a program I wrote to list the memory usage of all available processes so that I can clear memory from specific processes. My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 26, 2007 Share Posted September 26, 2007 Woo Hoo! I think I found it! expandcollapse popup#include <array.au3> ; for _ArrayDisplay() $avRET = _ProcessListProperties() _ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error) ;=============================================================================== ; Function Name: _ProcessListProperties() ; Description: Get various properties of a process, or all processes ; Call With: _ProcessListProperties( [$Process [, $sComputer]] ) ; Parameter(s): (optional) $Process - PID or name of a process, default is all ; (optional) $sComputer - remote computer to get list from, default is local ; Requirement(s): AutoIt v3.2.4.9+ ; Return Value(s): On Success - Returns a 2D array of processes, as in ProcessList() ; with additional columns added: ; [0][0] - Number of processes listed (can be 0 if no matches found) ; [1][0] - 1st process name ; [1][1] - 1st process PID ; [1][2] - 1st process Parent PID ; [1][3] - 1st process owner ; [1][4] - 1st process priority (0 = low, 31 = high) ; [1][5] - 1st process executable path ; [1][6] - 1st process CPU usage ; [1][7] - 1st process memory usage ; ... ; [n][0] thru [n][7] - last process properties ; On Failure: Returns array with [0][0] = 0 and sets @Error to non-zero (see code below) ; Author(s): PsaltyDS at http://www.autoitscript.com/forum ; Notes: If a numeric PID or string process name is provided and no match is found, ; then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList) ; This function requires admin permissions to the target computer. ; All properties come from the Win32_Process class in WMI. ;=============================================================================== Func _ProcessListProperties($Process = "", $sComputer = ".") Local $sUserName, $sMsg, $sUserDomain, $avProcs If $Process = "" Then $avProcs = ProcessList() Else $avProcs = ProcessList($Process) EndIf ; Return for no matches If $avProcs[0][0] = 0 Then Return $avProcs ; ReDim array for additional property columns ReDim $avProcs[$avProcs[0][0] + 1][8] ; Connect to WMI and get process objects $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2") If IsObj($oWMI) Then ; Get collection of all processes from Win32_Process $colProcs = $oWMI.ExecQuery ("select * from win32_process") If IsObj($colProcs) Then ; For each process... For $oProc In $colProcs ; Find it in the array For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.ProcessId Then ; [n][2] = Parent PID $avProcs[$n][2] = $oProc.ParentProcessId ; [n][3] = Owner If $oProc.GetOwner ($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName ; [n][4] = Priority $avProcs[$n][4] = $oProc.Priority ; [n][5] = Executable path $avProcs[$n][5] = $oProc.ExecutablePath ExitLoop EndIf Next Next Else SetError(2) ; Error getting process collection from WMI EndIf ; Get collection of all processes from Win32_PerfFormattedData_PerfProc_Process ; Have to use an SWbemRefresher to pull the collection, or all Perf data will be zeros Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher") $colProcs = $oRefresher.AddEnum ($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet $oRefresher.Refresh ; Time delay before calling refresher Local $iTime = TimerInit() Do Sleep(10) Until TimerDiff($iTime) > 100 $oRefresher.Refresh ; Get PerfProc data For $oProc In $colProcs ; Find it in the array For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.IDProcess Then $avProcs[$n][6] = $oProc.PercentProcessorTime $avProcs[$n][7] = $oProc.WorkingSet ExitLoop EndIf Next Next Else SetError(1) ; Error connecting to WMI EndIf ; Return array Return $avProcs EndFunc ;==>_ProcessListProperties Call it with $avRET = _ProcessListProperties($PID) where $PID is the process ID you want the info for, and $avRET[1][7] should be the memory usage. I had been in that WMI function before, but didn't see that the .WorkingSet property was what the TaskManager seems to report for process memory usage. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Siao Posted September 26, 2007 Share Posted September 26, 2007 (edited) Although the WMI method posted above and the Computer Info UDF mentioned by Saunders (probably uses WMI too) solve the topic, so this will be kind of redundant, but for learning purposes... This looks like it might do it: GetProcessMemoryInfo Function Uses PSAPI.dll which comes with Windows (NT and above at least), but I don't know enough about DLLs yet to figure out the call from AutoIt.Call it like this: Run("notepad") WinWait("Untitled - Notepad") MsgBox(0,"",_ProcessGetMem("notepad.exe")) Func _ProcessGetMem($sProcess) ;get process ID $nPID = ProcessExists($sProcess) If $nPID = 0 Then Return -1 ;get process handle, required for GetProcessMemoryInfo $aRet = DllCall("Kernel32.dll", "int", "OpenProcess", _ "dword", $PROCESS_QUERY_INFORMATION+$PROCESS_VM_READ, "dword", False, "dword", $nPID) If @error Or ($aRet[0] = 0) Then Return -1 $hProc = $aRet[0] ;create PPROCESS_MEMORY_COUNTERS to receive data, required for GetProcessMemoryInfo $structPROCESS_MEMORY_COUNTERS = DllStructCreate("dword; dword; uint peakmemsize; uint memsize; uint; uint; uint; uint; uint; uint") $nSize = DllStructGetSize($structPROCESS_MEMORY_COUNTERS) ;call GetProcessMemoryInfo $aRet = DllCall("Psapi.dll", "int", "GetProcessMemoryInfo", _ "hwnd", $hProc, "ptr", DllStructGetPtr($structPROCESS_MEMORY_COUNTERS), "dword", $nSize) ;close process handle DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hProc) ;return memory size in kb Return DllStructGetData($structPROCESS_MEMORY_COUNTERS, "memsize") / 1024 EndFunc Edited September 26, 2007 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 26, 2007 Share Posted September 26, 2007 Although the WMI method posted above and the Computer Info UDF mentioned by Saunders (probably uses WMI too) solve the topic, so this will be kind of redundant, but for learning purposes... Oh, you 'da man! Thanks! I had to add this to get it to run though: Global Const $PROCESS_QUERY_INFORMATION = 0x400 Global Const $PROCESS_VM_READ = 0x10 JSThePatriot's UDF does in fact use the same WMI Win32_Process interface I used for the first six properties in mine. He's using the .WorkingSetSize property from there, and I used the .WorkingSet property from Win32_PerfFormattedData_PerfProc_Process because I already had it open for the percent processor time, which the Win32_Process interface doesn't provide (I don't think so, anyway). My input parameter options are different, too. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Sars! Posted September 26, 2007 Author Share Posted September 26, 2007 Thanx for the help all! Finally I can get further. Grtz, Sars! Link to comment Share on other sites More sharing options...
crashdemons Posted November 14, 2007 Share Posted November 14, 2007 Woo Hoo! I think I found it! expandcollapse popup#include <array.au3> ; for _ArrayDisplay() $avRET = _ProcessListProperties() _ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error) ;=============================================================================== ; Function Name: _ProcessListProperties() ; Description: Get various properties of a process, or all processes ; Call With: _ProcessListProperties( [$Process [, $sComputer]] ) ; Parameter(s): (optional) $Process - PID or name of a process, default is all ; (optional) $sComputer - remote computer to get list from, default is local ; Requirement(s): AutoIt v3.2.4.9+ ; Return Value(s): On Success - Returns a 2D array of processes, as in ProcessList() ; with additional columns added: ; [0][0] - Number of processes listed (can be 0 if no matches found) ; [1][0] - 1st process name ; [1][1] - 1st process PID ; [1][2] - 1st process Parent PID ; [1][3] - 1st process owner ; [1][4] - 1st process priority (0 = low, 31 = high) ; [1][5] - 1st process executable path ; [1][6] - 1st process CPU usage ; [1][7] - 1st process memory usage ; ... ; [n][0] thru [n][7] - last process properties ; On Failure: Returns array with [0][0] = 0 and sets @Error to non-zero (see code below) ; Author(s): PsaltyDS at http://www.autoitscript.com/forum ; Notes: If a numeric PID or string process name is provided and no match is found, ; then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList) ; This function requires admin permissions to the target computer. ; All properties come from the Win32_Process class in WMI. ;=============================================================================== Func _ProcessListProperties($Process = "", $sComputer = ".") Local $sUserName, $sMsg, $sUserDomain, $avProcs If $Process = "" Then $avProcs = ProcessList() Else $avProcs = ProcessList($Process) EndIf ; Return for no matches If $avProcs[0][0] = 0 Then Return $avProcs ; ReDim array for additional property columns ReDim $avProcs[$avProcs[0][0] + 1][8] ; Connect to WMI and get process objects $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2") If IsObj($oWMI) Then ; Get collection of all processes from Win32_Process $colProcs = $oWMI.ExecQuery ("select * from win32_process") If IsObj($colProcs) Then ; For each process... For $oProc In $colProcs ; Find it in the array For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.ProcessId Then ; [n][2] = Parent PID $avProcs[$n][2] = $oProc.ParentProcessId ; [n][3] = Owner If $oProc.GetOwner ($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName ; [n][4] = Priority $avProcs[$n][4] = $oProc.Priority ; [n][5] = Executable path $avProcs[$n][5] = $oProc.ExecutablePath ExitLoop EndIf Next Next Else SetError(2) ; Error getting process collection from WMI EndIf ; Get collection of all processes from Win32_PerfFormattedData_PerfProc_Process ; Have to use an SWbemRefresher to pull the collection, or all Perf data will be zeros Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher") $colProcs = $oRefresher.AddEnum ($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet $oRefresher.Refresh ; Time delay before calling refresher Local $iTime = TimerInit() Do Sleep(10) Until TimerDiff($iTime) > 100 $oRefresher.Refresh ; Get PerfProc data For $oProc In $colProcs ; Find it in the array For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.IDProcess Then $avProcs[$n][6] = $oProc.PercentProcessorTime $avProcs[$n][7] = $oProc.WorkingSet ExitLoop EndIf Next Next Else SetError(1) ; Error connecting to WMI EndIf ; Return array Return $avProcs EndFunc ;==>_ProcessListProperties Call it with $avRET = _ProcessListProperties($PID) where $PID is the process ID you want the info for, and $avRET[1][7] should be the memory usage. I had been in that WMI function before, but didn't see that the .WorkingSet property was what the TaskManager seems to report for process memory usage. This function works great with one small issue If I call this function at the same time as process is closing, I will get an error: The requested action with this object has failed.: If $oProc.GetOwner ($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName If $oProc.GetOwner ($sUserName, $sUserDomain) ^ ERROR AutoIt 3.2.9.4 My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.) Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 14, 2007 Share Posted November 14, 2007 This function works great with one small issue If I call this function at the same time as process is closing, I will get an error: The requested action with this object has failed.: If $oProc.GetOwner ($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName If $oProc.GetOwner ($sUserName, $sUserDomain) ^ ERROR AutoIt 3.2.9.4 Hmm... interesting problem. Thanks for finding and reporting that. To keep the error from interrupting your script just add a COM error handler: $oMyError = ObjEvent("AutoIt.Error","MyErrFunc") ; Install a custom error handler ; ... Rest of the script ; This is my custom error handler Func MyErrFunc() $HexNumber=hex($oMyError.number,8) ConsoleWrite("Debug: Intercepted COM Error: Number = " & $HexNumber & _ " Windescription = " & $oMyError.windescription & @LF) SetError(1) ; something to check for when this function returns Endfunc As for the error itself, I looked at having the the function test for existence of the process as it loops, but that leads to a question: Does the coder want to know about that disappearing process or not? If not, we just delete it from the array and ignore it. But if they are interested in it, then null data might be more appropriate. This is relatively likely to come up, since a fairly long 100ms delay is required to make the WbemScripting.SWbemRefresher work correctly, there is plenty of time for a processes to close (or open) while the function is running. On my system, when run without parameters to list all processes, it takes about 2.7sec on the first run and about 1.3sec for each run after that (some Windows caching speeds up repeated use of the WMI, I believe). That's a long time in CPU cycles and the life a process. Here's what I'm thinking would be most useful to most people: 1. Add a COM error handler to your script any time you use COM methods in this function or any other (some UDFs like IE.au3 have their own). 2. Mod the function to return a value (like in @extended) to indicate if the process list changed while the function ran. I would like to hear what other think would be the best generic behavior for this function and I will post a modified version. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
weaponx Posted November 14, 2007 Share Posted November 14, 2007 Can you use ObjName ( $Objectvariable [,Flag] ) on $oProc to make sure it is the correct type of object before attempting to retrieve the owner? Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 14, 2007 Share Posted November 14, 2007 (edited) Actually, I haven't been able to reproduce the COM error. I tested it this way, with a debug hack in the middle of the function that kills notepad.exe after the process collection is retrieved, but before its properties are gathered. When I do this, notepad.exe is listed in the returned array with all null properties, as expected and no COM error, even though I don't have a COM error handler installed set up: expandcollapse popup#include <array.au3> ; for _ArrayDisplay() $PID = Run("notepad.exe") $iTotalTime = TimerInit() $avRET = _ProcessListProperties() $iTotalTime = Round(TimerDiff($iTotalTime) / 1000, 3) _ArrayDisplay($avRET, "Debug: $avProcs, $iTotalTime = " & $iTotalTime & "secs") ;=============================================================================== ; Function Name: _ProcessListProperties() ; Description: Get various properties of a process, or all processes ; Call With: _ProcessListProperties( [$Process [, $sComputer]] ) ; Parameter(s): (optional) $Process - PID or name of a process, default is all ; (optional) $sComputer - remote computer to get list from, default is local ; Requirement(s): AutoIt v3.2.4.9+ ; Return Value(s): On Success - Returns a 2D array of processes, as in ProcessList() ; with additional columns added: ; [0][0] - Number of processes listed (can be 0 if no matches found) ; [1][0] - 1st process name ; [1][1] - 1st process PID ; [1][2] - 1st process Parent PID ; [1][3] - 1st process owner ; [1][4] - 1st process priority (0 = low, 31 = high) ; [1][5] - 1st process executable path ; [1][6] - 1st process CPU usage ; [1][7] - 1st process memory usage ; ... ; [n][0] thru [n][7] - last process properties ; On Failure: Returns array with [0][0] = 0 and sets @Error to non-zero (see code below) ; Author(s): PsaltyDS at http://www.autoitscript.com/forum ; Notes: If a numeric PID or string process name is provided and no match is found, ; then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList) ; This function requires admin permissions to the target computer. ; All properties come from the Win32_Process class in WMI. ;=============================================================================== Func _ProcessListProperties($Process = "", $sComputer = ".") Local $sUserName, $sMsg, $sUserDomain, $avProcs If $Process = "" Then $avProcs = ProcessList() Else $avProcs = ProcessList($Process) EndIf ; Return for no matches If $avProcs[0][0] = 0 Then Return $avProcs ; ReDim array for additional property columns ReDim $avProcs[$avProcs[0][0] + 1][8] ; Connect to WMI and get process objects $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2") If IsObj($oWMI) Then ; Get collection of all processes from Win32_Process $colProcs = $oWMI.ExecQuery("select * from win32_process") If IsObj($colProcs) Then ; !!! --------------------------------------------------------------!!! ; Debug: kill notepad so the proces is gone before checking the object ProcessClose($PID, 1) ProcessWaitClose($PID, 2) ; !!! --------------------------------------------------------------!!! ; For each process... For $oProc In $colProcs ; Find it in the array For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.ProcessId Then ; [n][2] = Parent PID $avProcs[$n][2] = $oProc.ParentProcessId ; [n][3] = Owner If $oProc.GetOwner($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName ; [n][4] = Priority $avProcs[$n][4] = $oProc.Priority ; [n][5] = Executable path $avProcs[$n][5] = $oProc.ExecutablePath ExitLoop EndIf Next Next Else SetError(2) ; Error getting process collection from WMI EndIf ; Get collection of all processes from Win32_PerfFormattedData_PerfProc_Process ; Have to use an SWbemRefresher to pull the collection, or all Perf data will be zeros Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher") $colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet $oRefresher.Refresh ; Time delay before calling refresher Local $iTime = TimerInit() Do Sleep(10) Until TimerDiff($iTime) > 100 $oRefresher.Refresh ; Get PerfProc data For $oProc In $colProcs ; Find it in the array For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.IDProcess Then $avProcs[$n][6] = $oProc.PercentProcessorTime $avProcs[$n][7] = $oProc.WorkingSet ExitLoop EndIf Next Next Else SetError(1) ; Error connecting to WMI EndIf ; Return array Return $avProcs EndFunc ;==>_ProcessListProperties I've tried it on two machines, one has much better hardware specs than the other, but they are both XP Pro SP2 running AutoIt 3.2.8.1 Production and 3.2.9.9 Beta. Anybody get a COM error out of this on a different config? Edited November 14, 2007 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
weaponx Posted November 14, 2007 Share Posted November 14, 2007 I got the error by putting a MsgBox right after $colProcs = $oWMI.ExecQuery ("select * from win32_process"), closing any application, then click OK on the MsgBox. Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 14, 2007 Share Posted November 14, 2007 Now, just wait a cotton pick'n minute! I just ran it several times as above without errors. Then I ran it with this change: ; !!! --------------------------------------------------------------!!! ; Debug: kill notepad so the proces is gone before checking the object ;ProcessClose($PID, 1) ;ProcessWaitClose($PID, 2) MsgBox(64, "Breakpoint", "Breakpoint") ; Per WeaponX ; !!! --------------------------------------------------------------!!! Closing notepad while the MsgBox was up caused the problem, cool! But then put the original ProcessClose method back, and I'm still getting the COM error indication... Wha...? Waited a few minutes and tried it again, no COM error. Ran it again within a few seconds -- got COM error... Wha...? My computer is mocking me... Did it again with the COM error handler in place and it's the same, no error the first time, but I get this if I do it again quickly: >Running:(3.2.8.1):C:\Program Files\AutoIt3\autoit3.exe "C:\Scripts\Test\Test1.au3" Debug: Intercepted COM Error: Number = 80020009 Windescription = ???? +>14:10:14 AutoIT3.exe ended.rc:0 I still think the best solution is to just use the function as is and be sure to have a COM error handler in place any time you use COM objects in your scripts. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
weaponx Posted November 14, 2007 Share Posted November 14, 2007 Haha good stuff. Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 14, 2007 Share Posted November 14, 2007 Didn't take long to change my mind on that. This change prevents any COM errors, as per Weaponx' suggestion earlier: ; For each process... For $oProc In $colProcs $sObjName = ObjName($oProc, 3) ; 3 = ProgID If @error Then ContinueLoopoÝ÷ Ù*-êZµÈ^v÷«²*'¡ûayû§rبz0$²X¤zØb±«¢+Øìôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôô(ìչѥ½¸9µè}AɽÍÍ1¥ÍÑAɽÁÉÑ¥Ì ¤(ìÍÉ¥ÁÑ¥½¸èÐÙÉ¥½ÕÌÁɽÁÉѥ̽ÁɽÍÌ°½È±°ÁɽÍÍÌ(ì ±°]¥Ñ è}AɽÍÍ1¥ÍÑAɽÁÉÑ¥Ì lÀÌØíAɽÍÌl°ÀÌØíÍ ½µÁÕÑÉut¤(ìAɵÑȡ̤衽ÁÑ¥½¹°¤ÀÌØíAɽÍÌ´A%½È¹µ½ÁɽḬ́ձХ̱°(졽ÁÑ¥½¹°¤ÀÌØíÍ ½µÁÕÑȴɵ½Ñ½µÁÕÑÈѼб¥ÍÐɽ´°Õ±Ð¥Ì±½°(ìIÅեɵ¹Ð¡Ì¤èÕѽ%ÐØ̸ȸиä¬(ìIÑÕɸY±Õ¡Ì¤è=¸MÕÍÌ´IÑÕɹÌÉÉÉä½ÁɽÍÍÌ°Ì¥¸AɽÍÍ1¥ÍÐ ¤(ìÝ¥Ñ ¥Ñ¥½¹°½±Õµ¹Ìè(ìlÁulÁt´9յȽÁɽÍÍ̱¥ÍÑ¡¸À¥¹¼µÑ¡Ì½Õ¹¤(ìlÅulÁt´ÅÍÐÁɽÍ̹µ(ìlÅulÅt´ÅÍÐÁɽÍÌA%(ìlÅulÉt´ÅÍÐÁɽÍÌAɹÐA%(ìlÅulÍt´ÅÍÐÁɽÍ̽ݹÈ(ìlÅulÑt´ÅÍÐÁɽÍÌÁÉ¥½É¥Ñä Àô±½Ü°ÌÄô¡¥ ¤(ìlÅulÕt´ÅÍÐÁɽÍÌáÕѱÁÑ (ìlÅulÙt´ÅÍÐÁɽÍÌ ATÕÍ(ìlÅulÝt´ÅÍÐÁɽÍ̵µ½ÉäÕÍ(츸¸(ìm¹ulÁtÑ¡ÉÔm¹ulÝt´±ÍÐÁɽÍÌÁɽÁÉÑ¥Ì(ì=¸¥±ÕÉèIÑÕɹÌÉÉäÝ¥Ñ lÁulÁtôÀ¹ÍÑÌÉɽÈѼ¹½¸µéɼ¡Í½±½Ü¤(ìÕÑ¡½È¡Ì¤èAͱÑåLСÑÑÀè¼½ÝÝܹÕѽ¥ÑÍÉ¥Áй½´½½ÉÕ´(ì9½ÑÌè%¹ÕµÉ¥A%½ÈÍÑÉ¥¹ÁɽÍ̹µ¥ÌÁɽ٥¹¹¼µÑ ¥Ì½Õ¹°(ìÑ¡¸lÁulÁtôÀ¹ÉɽÈôÀ¡¹½ÐÑÉÑ̸ÉɽȰ͵ÌAɽÍÍ1¥ÍФ(ìQ¡¥Ìչѥ½¸ÉÅÕ¥É̵¥¸Áɵ¥ÍÍ¥½¹ÌѼѡÑÉнµÁÕÑȸ(ì±°ÁɽÁÉѥ̽µÉ½´Ñ¡]¥¸ÌÉ}AɽÍ̱ÍÌ¥¸]5$¸(ìôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôô)Õ¹}AɽÍÍ1¥ÍÑAɽÁÉÑ¥Ì ÀÌØíAɽÍÌôÅÕ½ÐìÅÕ½Ðì°ÀÌØíÍ ½µÁÕÑÈôÅÕ½Ðì¸ÅÕ½Ðì¤(1½°ÀÌØíÍUÍÉ9µ°ÀÌØíÍ5Í°ÀÌØíÍUÍɽµ¥¸°ÀÌØíÙAɽÌ(%ÀÌØíAɽÍÌôÅÕ½ÐìÅÕ½ÐìQ¡¸(ÀÌØíÙAɽÌôAɽÍÍ1¥ÍÐ ¤(±Í(ÀÌØíÙAɽÌôAɽÍÍ1¥ÍÐ ÀÌØíAɽÍ̤(¹%((ìIÑÕɸ½È¹¼µÑ¡Ì(%ÀÌØíÙAɽÍlÁulÁtôÀQ¡¸IÑÕɸÀÌØíÙAɽÌ((ìI¥´ÉÉä½È¥Ñ¥½¹°ÁɽÁÉÑä½±Õµ¹Ì(I¥´ÀÌØíÙAɽÍlÀÌØíÙAɽÍlÁulÁt¬Åulát((ì ½¹¹ÐѼ]5$¹ÐÁɽÍ̽©ÑÌ(ÀÌØí½]5$ô=©Ð ÅÕ½ÐíÝ¥¹µµÑÌéí¥µÁÉͽ¹Ñ¥½¹1Ù°õ¥µÁÉͽ¹ÑôÌÌìÀäÈìÀäÈìÅÕ½ÐìµÀìÀÌØíÍ ½µÁÕÑȵÀìÅÕ½ÐìÀäÈíɽ½ÐÀäÈí¥µØÈÅÕ½Ðì¤(%%Í=¨ ÀÌØí½]5$¤Q¡¸(ìн±±Ñ¥½¸½±°ÁɽÍÍÌɽ´]¥¸ÌÉ}AɽÍÌ(ÀÌØí½±AɽÌôÀÌØí½]5$¹áEÕÉä ÅÕ½ÐíͱШɽ´Ý¥¸ÌÉ}ÁɽÍÌÅÕ½Ðì¤(%%Í=¨ ÀÌØí½±Aɽ̤Q¡¸($$$ì½È ÁɽÍ̸¸¸($$%½ÈÀÌØí½Aɽ%¸ÀÌØí½±AɽÌ($$$$ÀÌØíÍ=©9µô=©9µ ÀÌØí½Aɽ°Ì¤ìÌôAɽ%($$$%%ÉɽÈQ¡¸ ½¹Ñ¥¹Õ1½½ÀìM¥À¥ÁɽÍ̹¼±½¹Èá¥ÍÑÌ(쥹¥Ð¥¸Ñ¡ÉÉä(½ÈÀÌØí¸ôÄQ¼ÀÌØíÙAɽÍlÁulÁt(%ÀÌØíÙAɽÍlÀÌØí¹ulÅtôÀÌØí½Aɽ¹AɽÍÍ%Q¡¸((ìm¹ulÉtôAɹÐA%(ÀÌØíÙAɽÍlÀÌØí¹ulÉtôÀÌØí½Aɽ¹AɹÑAɽÍÍ%(ìm¹ulÍtô=ݹÈ(%ÀÌØí½Aɽ¹Ñ=Ý¹È ÀÌØíÍUÍÉ9µ°ÀÌØíÍUÍɽµ¥¸¤ôÀQ¡¸ÀÌØíÙAɽÍlÀÌØí¹ulÍtôÀÌØíÍUÍɽµ¥¸µÀìÅÕ½ÐìÀäÈìÅÕ½ÐìµÀìÀÌØíÍUÍÉ9µ(ìm¹ulÑtôAÉ¥½É¥Ñä(ÀÌØíÙAɽÍlÀÌØí¹ulÑtôÀÌØí½Aɽ¹AÉ¥½É¥Ñä(ìm¹ulÕtôáÕѱÁÑ (ÀÌØíÙAɽÍlÀÌØí¹ulÕtôÀÌØí½Aɽ¹áÕѱAÑ ((á¥Ñ1½½À(¹%(9áÐ(9áÐ(±Í(MÑÉÉ½È È¤ìÉɽÈÑÑ¥¹ÁɽÍ̽±±Ñ¥½¸É½´]5$(¹%((ìн±±Ñ¥½¸½±°ÁɽÍÍÌɽ´]¥¸ÌÉ}AɽɵÑÑÑ}AÉAɽ}AɽÍÌ(ì!ÙѼÕ͸M]µIÉÍ¡ÈѼÁÕ±°Ñ¡½±±Ñ¥½¸°½È±°AÉÑÝ¥±°éɽÌ(1½°ÀÌØí½IÉÍ¡Èô=© ÉÑ ÅÕ½Ðí]µMÉ¥ÁÑ¥¹¹M]µIÉÍ¡ÈÅÕ½Ðì¤(ÀÌØí½±AɽÌôÀÌØí½IÉ͡ȹ¹Õ´ ÀÌØí½]5$°ÅÕ½Ðí]¥¸ÌÉ}AɽɵÑÑÑ}AÉAɽ}AɽÍÌÅÕ½Ð줹½©ÑMÐ(ÀÌØí½IÉ͡ȹIÉÍ ((ìQ¥µ±ä½É±±¥¹ÉÉÍ¡È(1½°ÀÌØí¥Q¥µôQ¥µÉ%¹¥Ð ¤(¼(M±À ÄÀ¤(U¹Ñ¥°Q¥µÉ¥ ÀÌØí¥Q¥µ¤ÐìÄÀÀ(ÀÌØí½IÉ͡ȹIÉÍ ((ìÐAÉAɽÑ(½ÈÀÌØí½Aɽ%¸ÀÌØí½±AɽÌ(쥹¥Ð¥¸Ñ¡ÉÉä(½ÈÀÌØí¸ôÄQ¼ÀÌØíÙAɽÍlÁulÁt(%ÀÌØíÙAɽÍlÀÌØí¹ulÅtôÀÌØí½Aɽ¹%AɽÍÌQ¡¸(ÀÌØíÙAɽÍlÀÌØí¹ulÙtôÀÌØí½Aɽ¹AɹÑAɽÍͽÉQ¥µ(ÀÌØíÙAɽÍlÀÌØí¹ulÝtôÀÌØí½Aɽ¹]½É¥¹MÐ(á¥Ñ1½½À(¹%(9áÐ(9áÐ(±Í(MÑÉÉ½È Ä¤ìÉɽȽ¹¹Ñ¥¹Ñ¼]5$(¹%((ìIÑÕɸÉÉä(IÑÕɸÀÌØíÙAɽÌ)¹Õ¹ìôôÐí}AɽÍÍ1¥ÍÑAɽÁÉÑ¥Ì Cheers, and thanks to Weaponx. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law 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