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

梦回上玄 · · 686 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

前言

有一次我服务器中招了频繁的弹出重启对话框并重启的事情(进入安全模式没有找到和启动此命令有关的程序),我不得不在有限的时间里尝试找到此进程并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

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:梦回上玄

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

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

686 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传