killerczz 2023-02-21 10:34 采纳率: 100%
浏览 89
已结题

python下通过ctypes使用原生C函数获取进程名(szExeFile)失败问题

#python下通过ctypes使用原生C函数获取进程名(szExeFile)失败问题
代码如下:

from ctypes.wintypes import DWORD

from ctypes import (
    Structure,
    c_char,
    sizeof,
    byref,
    windll,
)

PATH_MAX= c_char*265 #为什么我的不能小与265?别人是260

class structure(Structure): #参照C自制结构体
    _fields_ = [
        ('dwSize',DWORD),
        ('cntUsage',DWORD),
          ('th32ProcessID',DWORD),
          ('th32DefaultHeapID',DWORD),
          ('th32ModuleID',DWORD),
          ('cntThreads',DWORD),
          ('th32ParentProcessID',DWORD),
          ('pcPriClassBase',DWORD),
          ('dwFlags',DWORD),
          ('szExeFile',PATH_MAX) #注意这个值
        ]
def win32showprocess():
    CreateToolhelp32Snapshot=windll.kernel32.CreateToolhelp32Snapshot #获取进程快照
    store_struc=structure() 
    store_struc.dwSize=sizeof(structure) #初始化结构体
    kz_handle=CreateToolhelp32Snapshot(0x2,0) 
    if windll.kernel32.Process32First(kz_handle,byref(store_struc)):
        while windll.kernel32.Process32Next(kz_handle,byref(store_struc)):
            yield store_struc
processlist=win32showprocess()

#以下代码试图通过for循环获取进程名称,结果与预期不符,得到单个的char,似乎也不是首字母。不知道是什么。如下:

for processinfo in processlist:
    print('进程ID:%d\t进程名称:%s'%(processinfo.th32ProcessID,processinfo.szExeFile))

进程ID:4 进程名称:b'\x08'
进程ID:236 进程名称:b'\x08'

#我尝试使用psutil模块获取进程名称,结果如预期一致:

from psutil import Process
for processinfo in processlist:
    print('进程ID:%d\t进程名称:%s'%(processinfo.th32ProcessID,Process(processinfo.th32ProcessID).name()))

进程ID:4 进程名称:System
进程ID:236 进程名称:Registry

使用环境window10 python3.9.13
输出时szExeFile的类型为‘bytes’,所有长度均为1,怀疑是在szExeFile写入时就出了问题。
问题:第一个for的问题处在哪里?产生的原因是什么,怎么避免。

  • 写回答

7条回答 默认 最新

  • 「已注销」 2023-02-21 17:12
    关注

    你应该看看 Process32First 参数 PROCESSENTRY32的原型

    typedef struct tagPROCESSENTRY32 {
      DWORD     dwSize;
      DWORD     cntUsage;
      DWORD     th32ProcessID;
      ULONG_PTR th32DefaultHeapID;
      DWORD     th32ModuleID;
      DWORD     cntThreads;
      DWORD     th32ParentProcessID;
      LONG      pcPriClassBase;
      DWORD     dwFlags;
      CHAR      szExeFile[MAX_PATH];
    } PROCESSENTRY32;
    
    th32DefaultHeapID 的类型是ULONG_PTR,他表示一个指针长度的无符号整型,
    也就是说如果你的 python是64位版本那么这个变量的长度就是8字节
    python32位版本那么这个变量的长度就是4字节
    那么你应该使用 c_void_p 
    
    
    ```python
    
    from ctypes import c_void_p 
    
    class structure(Structure):
        _fields_ = [
            ('dwSize',DWORD),
            ('cntUsage',DWORD),
              ('th32ProcessID',DWORD),
              ('th32DefaultHeapID', c_void_p ), #修改这里
              ('th32ModuleID',DWORD),
              ('cntThreads',DWORD),
              ('th32ParentProcessID',DWORD),
              ('pcPriClassBase',DWORD),
              ('dwFlags',DWORD),
              ('szExeFile', c_char *260 ) # winapi 宏定义 MAX_PATH 值是 260 
            ]
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 3月2日
  • 已采纳回答 2月22日
  • 修改了问题 2月21日
  • 修改了问题 2月21日
  • 展开全部

悬赏问题

  • ¥30 matlab appdesigner私有函数嵌套整合
  • ¥15 给我一个openharmony跑通webrtc实现视频会议的简单demo项目,sdk为12
  • ¥15 vb6.0使用jmail接收smtp邮件并另存附件到D盘
  • ¥30 vb net 使用 sendMessage 如何输入鼠标坐标
  • ¥15 关于freesurfer使用freeview可视化的问题
  • ¥100 谁能在荣耀自带系统MagicOS版本下,隐藏手机桌面图标?
  • ¥15 求SC-LIWC词典!
  • ¥20 有关esp8266连接阿里云
  • ¥15 C# 调用Bartender打印机打印
  • ¥15 我这个代码哪里有问题 acm 平台上显示错误 90%,我自己运行好像没什么问题