python小工具--查看窗口程序进程

2020-12-26  本文已影响0人  梦回上玄

前言

有一次我服务器中招了频繁的弹出重启对话框并重启的事情(进入安全模式没有找到和启动此命令有关的程序),我不得不在有限的时间里尝试找到此进程并Kill掉它,使用pchunter和process monitor均没有在有限的时间内找到正确的进程,后来发现好像也没有类似的小工具,于是绝对自己写一个。

​ windows的朋友都知道对于windows来说最重要的两个系统API库就是kernel32.dll和user32.dll,kernel32.dll主要是和内核交互我们此时用不到,user32.dll主要是处理windows用户界面的api库,正是我们需要的。于是我找到了user32.dll的库开发文档,打算用golang写一个小工具。

2000 years later...

放弃了,不是windows开发者,看user32.dll还是短时间存在一定困难,且golang没有相关的调用库,直接load user32.dll感觉是找麻烦。此时又想起python大法,发现python最优秀的地方就是库太多了,存在pywin32这么个库来转接windows的API。

需求

设计实现

考虑把大象放冰箱鼠标点击一下就能查看窗体的进程号分几步:

pywin32的函数命名和user32.dll的库函数名字是类似的,于是我直接在pywin32的开发文档里面搜索CursorPos发现存在win32gui.GetCursorPos()函数获取鼠标坐标,操作很简单

from win32 import win32gui
point =win32gui.GetCursorPos()#point为鼠标坐标

对照User32的开发文档和pywin32的开发文档搜索出获取窗口句柄的函数、窗口标题、和窗口进程的函数

from win32 import win32gui,win32process
win32gui.WindowFromPoint()#获取当前窗口句柄
win32gui.GetWindowText()#获取当前窗口标题
win32process.GetWindowThreadProcessId() #获取当前窗口进程和线程

搜索pywin32关于mouse和CursorPos,没有发现有关于鼠标监听的函数,只搜到win32gui._TrackMouseEvent,我们知道“_”开头的函数一般是内部函数能用也不好用。要不怎么说python大法好呢,随便搜索下得知pynput库可以监听鼠标键盘事件,官方Demo代码足以。

最后实现我们的demo代码

from win32 import win32gui,win32process
from pynput.mouse import Listener,Button

while True:
    #官方鼠标监听Demo代码
    def on_click(x, y,button,pressed):
        if not pressed:
            return False
        
    with Listener( on_click=on_click,on_scroll=on_scroll) as listener:
        listener.join()
        point =win32gui.GetCursorPos()#获取鼠标坐标
        p=win32gui.WindowFromPoint(point)#获取鼠标坐标位置窗口句柄
        p_name=win32gui.GetWindowText(p)#获取窗口句柄对应的进程名
        _,p_id=win32process.GetWindowThreadProcessId(p)#获取窗口句柄对应的PID
        print(p_name,p_id)

执行Python xxx.py 测试没问题,然而pyinstaller打包失败,Pynput无法打包成pyd,作为应急使用,就不研究为啥打包失败了,考虑类似win32gui._TrackMouseEvent实现,我们可以利用Sleep函数自己简单实现鼠标悬停效果,都没10行代码就解决问题。

from win32 import win32gui,win32process
import time
while True:
    point1 =win32gui.GetCursorPos()#获取鼠标坐标
    time.sleep(2)#模拟鼠标两秒悬停
    point2 =win32gui.GetCursorPos()#获取鼠标坐标
    if point2 == point1:
        p=win32gui.WindowFromPoint(point2)#获取鼠标坐标位置窗口句柄
        p_name=win32gui.GetWindowText(p)#获取窗口句柄对应的进程名
        _,p_id=win32process.GetWindowThreadProcessId(p)#获取窗口句柄对应的PID
        print(p_name,p_id)

测试python xxx.py执行成功,pyinstaller打包测试成功。

代码实现

代码量不多,调整下格式即可:

#coding=utf-8
#date 2020.12.23
#depand:python3.8,win32
#描述:鼠标悬停窗体2秒输出进程名和PID
from win32 import win32gui,win32process
import time
import sys

def get_PID(point):
    try:
        p=win32gui.WindowFromPoint(point)    
        p_name=win32gui.GetWindowText(p)
        _,p_id=win32process.GetWindowThreadProcessId(p)
        print(p_name,p_id)
    except:
        print("win32获取窗体信息失败 error")
        sys.exit(1)

def main():
    while True:
        point1 =win32gui.GetCursorPos()#获取鼠标坐标
        time.sleep(2)
        point2 =win32gui.GetCursorPos()#获取鼠标坐标
        if point2 == point1:
           get_PID(point2)
if __name__ == "__main__":
    main()
  

使用Pyinstaller打包,打包完大概6.7mb,这也是Python无奈的地方,随便几行代码就这么大,最好还是用编译语言实现,几十kb就行了。本例中代码量不多,但是看win32的开发文档过程还是蛮痛苦的,希望能给大家提供一些思考问题的思路。Python版最后执行效果如下:

1.jpg
上一篇下一篇

猜你喜欢

热点阅读