如何避免Python Tkinter GUI转exe后执行Nmap时弹出控制台窗口?
解决Python-nmap打包exe后弹出控制台窗口的问题
问题原因
python-nmap库执行扫描时,会通过subprocess调用系统中的nmap.exe进程,默认会创建控制台窗口。即便PyInstaller用--noconsole参数抑制了主程序的控制台,子进程的控制台仍会弹出。
解决方案
方案一:修改python-nmap库源码
找到python-nmap的安装目录(比如虚拟环境下的Lib\site-packages\nmap),打开portscanner.py文件,找到所有调用subprocess.Popen的代码块,添加Windows平台特有的creationflags=subprocess.CREATE_NO_WINDOW参数,阻止子进程弹出控制台。
原代码片段示例:
proc = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True )
修改后代码:
import os import subprocess if os.name == 'nt': proc = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, creationflags=subprocess.CREATE_NO_WINDOW ) else: proc = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True )
修改完成后,重新用PyInstaller打包即可。
方案二:自行封装nmap调用逻辑(无需修改库源码)
放弃使用python-nmap库,直接通过subprocess调用nmap.exe并添加CREATE_NO_WINDOW参数,自行解析扫描结果。
修改后的示例代码:
import tkinter as tk import subprocess import os class App(tk.Tk): def __init__(mr): tk.Tk.__init__(mr) mr.entry = tk.Entry(mr) mr.entry.pack() mr.entry.bind('<Return>', lambda event: mr.scaner()) def scaner(mr): adr = mr.entry.get() nmap_args = '-F --host-timeout 3000ms --max-rtt-timeout 1000ms --max-retries 0 -Pn' # 若nmap未加入环境变量,需写完整路径,比如'C:\\Program Files (x86)\\Nmap\\nmap.exe' cmd = f'nmap {nmap_args} {adr}' # 调用nmap并抑制控制台窗口 if os.name == 'nt': result = subprocess.run( cmd, capture_output=True, text=True, creationflags=subprocess.CREATE_NO_WINDOW ) else: result = subprocess.run( cmd, capture_output=True, text=True ) # 解析输出判断是否存在开放/过滤的TCP端口 has_tcp = 'tcp' in result.stdout and ('open' in result.stdout or 'filtered' in result.stdout) mr.entry['background'] = 'green' if has_tcp else 'red' def Main(): app = App() app.mainloop() if __name__ == "__main__": Main()
内容的提问来源于stack exchange,提问作者shu9000
相关产品推荐
相关产品推荐

