有時候我們發現電腦上某個端口被佔用了,這就導致啓動不了一些服務。
而每次手動去找到並殺死進程實在是麻煩,於是用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,而成功將返回一個非零值。
本文結束~~~~