Jump to content

[Doubt] Get PID from handle


Recommended Posts

While 1

   $x = WinList('[CLASS:Proxifier32Cls]')

   For $i = 0 To $x[0][0]

   $title = $x[$i][0]
   $handle = $x[$i][1]

   If  StringInStr($title, "Expired") Then
    $PID = WinGetProcess($handle)
    $name = _Findpidname($PID)
    ConsoleWrite($name)
   EndIf

   Next
   Sleep(100)

WEnd


Func _Findpidname($PID)

       Local $Processlist = ProcessList()
       For $i = 1 To $Processlist[0][0]
           If $Processlist[$i][1] = $Pid Then Return $Processlist[$i][0]
           Next

EndFunc

I did this script to search for all window with [CLASS:Proxifier] and title "Expired", if any found then, get its process name using her handle.

I'm writing to ask if there's any other way i could do it, more "optimized", i mean, use less CPU, my script uses 15% cpu checking this loop constantly (its not a high end cpu pc), i cant increase the sleep because i need accurate real time data, atm i have 132 process opened, that's helps increase the load.

Link to comment
Share on other sites

Not sure if this will help, but you could possibly eliminate some code in your script by using a more complex WinList parameter, ie --

$x = WinList('[CLASS:Proxifier32Cls; TITLE:Expired]')

Then you would no longer need to do the StringInStr checking. Also, you could look at replacing your _Findpidname function with a call to _ProcessGetName.

Link to comment
Share on other sites

i would look for some text that appears only in windows of that application, and never in any other windows, and is visible to AutoIt (use the AutoIt Window Info tool, the "Visible Text" tab). once i've determined that, i would feed the keyword "Expired" to WinList() as the window title (instead of the class), and that text, to filter out other windows that might have "Expired" in their title. that way i could reduce your entire script to a single line.

EDIT: @Danp2 just beat me to it :-)

Edited by orbs

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

Thank you for the feedback's! 

@Danp2 Im using StringinStr because the title is not exactly, so it search if contains the word in the title.

@orbs I would still need know the process name of the window with the 'different' text.

What i thought: do a code to store all window handle with its own process name saved in a .ini file:

FileDelete("C:\Users\Matheus\Downloads\ProcessList.ini")
   $output = ("C:\Users\Matheus\Downloads\ProcessList.ini")
   $array = WinList('[CLASS:Proxifier32Cls]')

   $mm = 0

   While $mm <> $array[0][0] + 1
        $mmm = $array[$mm][1]
        $PIDmm = WinGetProcess($mmm)
        IniWrite($output, "Process List", "", "")
        FileWriteLine($output, $array[$mm][1] & "=" & _Findpidname($Pidmm))
       $mm = $mm + 1
   WEnd




Func _Findpidname($Pid) ; Função encontrar PID

       Local $Processlist = ProcessList()
       For $i = 1 To $Processlist[0][0]
           If $Processlist[$i][1] = $Pid Then Return $Processlist[$i][0]
           Next

EndFunc

Result in my processlist.ini:

[Process List]
=
=AutoIt3.exe
0x00010C84=9.exe
0x0001110C=13.exe
0x00010FEA=12.exe
0x00010EC8=11.exe
0x00011350=15.exe
0x000205B8=3.exe
0x000106DA=4.exe
0x00010A40=7.exe
0x000107FC=5.exe
0x00010498=2.exe
0x00040304=1.exe
0x0001122E=14.exe
0x00011594=17.exe
0x00011472=16.exe
0x00010DA6=10.exe
0x00010B62=8.exe
0x0001091E=6.exe

I have no idea why it always store "=" and "=AutoIt3.exe".

This way, i can skip the search on processlist in each loop (who causes the heavy load) and just compare the actual $handle in the array with the $handle stored in processlist.ini and gets it process name.

So i change:

If StringInStr($title, "Expi") Then

         $name = IniRead("C:\Users\Matheus\Download\ProcessList.ini", "Process List", $handle, "Default Value")
         ConsoleWrite($name)
         ConsoleWrite($handle)
         Global $Title = $name
         Call("

It gets the actual $handle in the array and search for it process name in the processlist.ini.

image.png.0296e58fb3cec60e254ae6a77f77ca1c.png0x0001110C = 13.exe in ProcessList.ini, but $name return Default Value

It should return the process name in the string $name, but its returning "Default Value", what am i doing wrong? 💁‍♀️

 

Edited by memerim
Link to comment
Share on other sites

memerim,

1 hour ago, memerim said:

Im using StringinStr because the title is not exactly, so it search if contains the word in the title.

for that case you maybe won't need to list by class .. Use:

 $array = WinList("[REGEXPTITLE:(?i)(.*Expired.*)]")

and why all the exe's  ?

simply use _FileListToArrayRec to make an array with all paths involved

Depending on what this is all about, that you are trying to do:  @guessing ..

make another function to update the array to delete or add paths ..etc after each step

 

because it doesn't make sense to run so many exe's at one time especially if they are made by you ..

If you must have all your script.exe's run separated, better first read and know your options about using $cmdline, Then take it on from there ..

Deye

 

Edited by Deye
Link to comment
Share on other sites

@memerim,

the suggestion by @Danp2 seems just the right thing for you - except that when you say...

2 hours ago, memerim said:

Im using StringinStr because the title is not exactly, so it search if contains the word in the title.

look at the help for WinList() - the explanation of the first parameter ("title") mentions you should look at the Title special definition help page - there are several search modes, one of them (mode 2) will search the string anywhere in the title. read that help page thoroughly - it explains how to use WinList() to list windows matching several conditions - class and title substring, for example.

i truly believe that a single WinList() command can successfully provide only the windows you are concerned with.

now, once you have that list, you can loop it to find the process name (as you already do). one shortcut you can use is WinGetProcess(), but - assuming all these processes are scripts written by you - you can be even smarter: have each process write its name and PID (and whatever other info you need) to a file named after the window handle. for example, your script 1.exe would write its PID into a file  named "00040304.txt". WinList() returns an array of handles, one of them is 0x00040304 - and you can read the file name derived from that handle to access directly the process information you need. only one loop throughout the entire operation!

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

I'd do it the other way round: if the many processes are your own, let them update a .INI file with their PID and name (at startup and termination). If those  aren't your own (i.e. you can't change their behavior), use an AutoIt launcher you can write yourself to do the same thing.

This way your .INI is always up to date and your CPU remains available. Only issue is insuring serialized access to avoid contention.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...