I've done some pretty extensive work with determining name of
executeables belonging to a window by Window Handle .. and here's what
I've come up with ,that seems to work 100% of the time, even on Vista:

        # Request privileges to enable "debug process", so we can
later use PROCESS_VM_READ, retardedly required to
GetModuleFileNameEx()
        priv_flags = win32security.TOKEN_ADJUST_PRIVILEGES |
win32security.TOKEN_QUERY
        hToken = win32security.OpenProcessToken
(win32api.GetCurrentProcess(), priv_flags)
        # enable "debug process"
        privilege_id = win32security.LookupPrivilegeValue (None,
win32security.SE_DEBUG_NAME)
        old_privs = win32security.AdjustTokenPrivileges (hToken, 0,
[(privilege_id, win32security.SE_PRIVILEGE_ENABLED)])

        # Open the process, and query it's filename
        processid = win32process.GetWindowThreadProcessId(hwnd)
        pshandle =
win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION |
win32con.PROCESS_VM_READ, False, processid[1])
        exename = win32process.GetModuleFileNameEx(pshandle, 0)

        # clean up
        win32api.CloseHandle(pshandle)
        win32api.CloseHandle(hToken)

The first block of code got it working in 100% of our users cases on
Vista (whereas previously, we could only get it if they were both
admin, and had the python executeable and the executeable we were
trying to query stored outside of the Program Files hierarchy).  Also,
without the two calls to CloseHandle, we would eventually leak
resources until the system was completely depleted of handles, and
then every other operation would fail, not just by our program, but by
every program, and even the Windows swapper would eventually crash and
bring the system down.

Lesson I've learned: Always clean up after yourself when you're
mucking about with the Windows API, Python won't do it for you.  (I
imagine others haven't mentioned to do this because others probably
don't need to run this routine bajillions of times, therefore don't
see their programs leaking like the proverbial sieves)



On Thu, Jul 23, 2009 at 6:00 AM, <python-win32-requ...@python.org> wrote:
> Send python-win32 mailing list submissions to
>        python-wi...@python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>        http://mail.python.org/mailman/listinfo/python-win32
> or, via email, send a message with subject or body 'help' to
>        python-win32-requ...@python.org
>
> You can reach the person managing the list at
>        python-win32-ow...@python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of python-win32 digest..."
>
>
> Today's Topics:
>
>   1. Re: handle is invalid? (reehdus)
>   2. Re: Trying to grab exe of foreground window (reehdus)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Wed, 22 Jul 2009 17:26:12 -0700 (PDT)
> From: reehdus <sudheer...@hotmail.com>
> To: python-win32@python.org
> Subject: Re: [python-win32] handle is invalid?
> Message-ID: <24617252.p...@talk.nabble.com>
> Content-Type: text/plain; charset=us-ascii
>
>
> ahha...that would explain a lot...nope...roger's method was excellent...I was
> trying this out before I saw his recipe. I see...well...pardon my ignorance
> since I'm pretty new at Python...it didn't really occur to me that
> FindWindow was redundant. Well, now I know better...hahaha. Thanks!
>
>
> Tim Roberts wrote:
>>
>> sudheer sivathasan wrote:
>>> Hey guys,
>>>
>>> Another quick question. I'm still trying to do the thing in the email
>>> below. But this time im trying to use the win32api.GetModuleFileName
>>> function. It requires a PyHandle as an input which I think I've
>>> managed to get by using the function handle =
>>> w.FindWindow(0,str(w.GetWindowText(w.GetForegroundWindow()))) where
>>> handle would serve as the input to the win32api.GetModuleFileName
>>> function and w = win32gui. However I'm getting a 'the handle is
>>> invalid' error.
>>
>> Yes, because FindWindow returns a window handle, and GetModuleFileName
>> expects a module handle.  Handles are not all alike.  Roger Upole gave
>> you exactly the recipe you need.  Was there something about his reply
>> that you didn't like?
>>
>> By the way, your code there is somewhat silly: the FindWindow call will
>> return exactly the same handle that GetForegroundWindow already gave you.
>>
>> --
>> Tim Roberts, t...@probo.com
>> Providenza & Boekelheide, Inc.
>>
>> _______________________________________________
>> python-win32 mailing list
>> python-win32@python.org
>> http://mail.python.org/mailman/listinfo/python-win32
>>
>>
>
> --
> View this message in context: 
> http://www.nabble.com/handle-is-invalid--tp24599116p24617252.html
> Sent from the Python - python-win32 mailing list archive at Nabble.com.
>
>
>
> ------------------------------
>
> Message: 2
> Date: Wed, 22 Jul 2009 17:36:39 -0700 (PDT)
> From: reehdus <sudheer...@hotmail.com>
> To: python-win32@python.org
> Subject: Re: [python-win32] Trying to grab exe of foreground window
> Message-ID: <24617345.p...@talk.nabble.com>
> Content-Type: text/plain; charset=us-ascii
>
>
>      Excellent...it works! Thanks...I put in the first sleep so I could test
> the program with various other applications, so it'd give me enough time to
> open up internet explorer or something...the second sleep was a
> typo...leftover from a bit of earlier code i did.
>      I see...I tried looking for documentation onw win32con to see what I
> needed but I couldn't muster up anything. All i got were
> win32con.PROCESS_TERMINATE and process query information so I assumed one of
> this was what I needed. Again...thanks so much for enlightening me.
>
> Sudheer
>
>
> Tim Roberts wrote:
>>
>> reehdus wrote:
>>> I tried that but I get stuck at EnumProcessModules. It tells me my access
>>> is
>>> denied. I'm not sure if I'm doing it right. My code is below:
>>>
>>> import win32gui
>>> import win32api
>>> import win32con
>>> from time import sleep
>>> import win32process
>>>
>>> sleep(2)
>>> name = win32gui.GetForegroundWindow()
>>> t,p = win32process.GetWindowThreadProcessId(name)
>>> handle = win32api.OpenProcess(1,False,p)
>>>
>>
>> The 1 there means PROCESS_TERMINATE.  That means you are only asking for
>> permission to terminate the process, not to enumerate its contents.  For
>> EnumProcessModules, you need PROCESS_QUERY_INFORMATION and
>> PROCESS_VM_READ, which would be 0x0410.
>>
>>> sleep(1)
>>> whee = win32process.EnumProcessModules(handle)
>>> nama = win32process.GetModuleFileNameEx(whee, 0)
>>> print nama
>>>
>>
>> Why are those "sleeps" in there?
>>
>> EnumProcessModules returns a tuple, containing all of the modules
>> currently loaded in the process.  You would need to choose one.
>> However, in this particular case, you don't need that call at all.
>> GetModuleFileNameEx takes a process handle, plus a module handle, or "0"
>> to mean the processes original exe.  So, you can replace those last four
>> lines with:
>>     print win32process.GetModuleFileNameEx( handle, 0 )
>>
>> --
>> Tim Roberts, t...@probo.com
>> Providenza & Boekelheide, Inc.
>>
>> _______________________________________________
>> python-win32 mailing list
>> python-win32@python.org
>> http://mail.python.org/mailman/listinfo/python-win32
>>
>>
>
> --
> View this message in context: 
> http://www.nabble.com/Trying-to-grab-exe-of-foreground-window-tp24582049p24617345.html
> Sent from the Python - python-win32 mailing list archive at Nabble.com.
>
>
>
> ------------------------------
>
> _______________________________________________
> python-win32 mailing list
> python-win32@python.org
> http://mail.python.org/mailman/listinfo/python-win32
>
>
> End of python-win32 Digest, Vol 76, Issue 24
> ********************************************
>



-- 
Cheers,
 - Eric
_______________________________________________
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to