有时候我们发现电脑上某个端口被占用了,这就导致启动不了一些服务。
而每次手动去找到并杀死进程实在是麻烦,于是用python写个自动的来整活。
除了使用常见的os模块,本文还有提供使用win32api的例子
主要面向windows平台
首先,已知用cmd执行 netstat -aon | findstr "端口号" 可以找到占用端口的进程pid
在python中可以使用 os 模块的 popen 方法执行cmd命令,如这样:
import os
result = os.popen('netstat -aon|findstr "443"')
返回的结果是一个文件对象,就像我们用open函数打开文件一样,需要读取它:
print(result.read())
当然也可以使用上下文管理器with,效果一样,写法更优雅:
with os.popen('netstat -aon|findstr "443"') as r:
result = r.read()
得到的结果就如下图,是字符串:
于是进行解析,方便操作:
import os
with os.popen('netstat -aon|findstr "443"') as res:
res = res.read().split('\n')
result = []
for line in res:
temp = [i for i in line.split(' ') if i != '']
if len(temp) > 4:
result.append({'pid': temp[4], 'address': temp[1], 'state': temp[3]})
得到的结果成了这样:
现在很方便操作了,因为我只需要部分数据,所以并没有取全部。
得到了进程pid,接下来是杀死进程。
还是可以通过执行cmd命令的方式来杀死进程,cmd命令:taskkill -pid 进程pid -f
依然可以用popen的方法去执行:
import os
result = os.popen("taskkill -pid 进程pid -f")
也可以使用win32api的TerminateProcess函数:
import win32api # 需要先pip install pywin32模块
handle = win32api.OpenProcess(1, False, "进程pid") # 获取进程句柄(pid类型为int!)
win32api.TerminateProcess(handle, 0) # 杀了它
win32api.CloseHandle(handle) # 关闭
这里说一下OpenProcess的第一个参数:
dwDesiredAccess,指的是进程访问权限
PROCESS_ALL_ACCESS //所有能获得的权限
PROCESS_CREATE_PROCESS //需要创建一个进程
PROCESS_CREATE_THREAD //需要创建一个线程
PROCESS_DUP_HANDLE //重复使用DuplicateHandle句柄
PROCESS_QUERY_INFORMATION //获得进程信息的权限,如它的退出代码、优先级
PROCESS_QUERY_LIMITED_INFORMATION /获得某些信息的权限,如果获得了PROCESS_QUERY_INFORMATION,也拥有PROCESS_QUERY_LIMITED_INFORMATION权限/
PROCESS_SET_INFORMATION //设置某些信息的权限,如进程优先级
PROCESS_SET_QUOTA //设置内存限制的权限,使用SetProcessWorkingSetSize
PROCESS_SUSPEND_RESUME //暂停或恢复进程的权限
PROCESS_TERMINATE //终止一个进程的权限,使用TerminateProcess
PROCESS_VM_OPERATION //操作进程内存空间的权限(可用VirtualProtectEx和WriteProcessMemory)
PROCESS_VM_READ //读取进程内存空间的权限,可使用ReadProcessMemory
PROCESS_VM_WRITE //读取进程内存空间的权限,可使用WriteProcessMemory
SYNCHRONIZE //等待进程终止
这里我们要结束进程,所以需要PROCESS_TERMINATE权限,也就是数字1
import win32con
win32con.PROCESS_TERMINATE # 也可以这样表示权限,更直观(返回结果是数字1)
同样,ctypes模块也可以做到上面这件事:
import ctypes
handle = ctypes.windll.kernel32.OpenProcess(1, False, "进程pid") # 同上(pid类型为int!)
ctypes.windll.kernel32.TerminateProcess(handle, -1)
ctypes.windll.kernel32.CloseHandle(handle)
哈哈,搞定了!
然后再说明一下TerminateProcess这个函数:
TerminateProcess(HANDLE hProcess,UINT uExitCode)
参数:
1、hProcess:要终止进程的句柄,需要先获取PROCESS_TERMINATE权限。
2、uExitCode:设置进程的退出值。可通过GetExitCodeProcess函数得到一个进程的退出值。
返回值:
如果失败将返回0,而成功将返回一个非零值。
本文结束~~~~