1、問題來源
本人之前撰寫過一個 使用nps搭建內網穿透並配置泛域名解析的教程,但其中的運行客户端程序使用的是 CMD 命令行進行操作,並且需要配置的參數較多,總是記不住。
所以就在考慮是否能將 cmd 命令程序轉成 EXE GUI程序,方便配置參數運行。本教程就營運而生了。
2、操作教程
2.1 原理
PySimpleGUI是一個用於創建圖形用户界面(GUI)的Python模塊。本教程使用 PySimpleGUI 為 NPS內網穿透客户端程序(v0.26.0)製作了一個GUI界面。
2.2 NPS\_GUI界面代碼
首先新建一個目錄為 nps_gui ,在目錄中新建一個 main.py 程序,並將與 nps 服務端配套的 npc.exe 文件複製到該目錄下。
main.py 程序為主程序,用來繪製 GUI 界面,調用 CMD 命令運行程序。
main.py 程序內容如下:
# main.py
import subprocess
import threading
import PySimpleGUI as sg
# 定義版本號和作者信息
version = "0.0.1"
author = "巧遇科技工作室"
about_me = "本程序是NPS內網穿透服務的GUI界面,用來輔助NPS內網穿透服務客户端進行使用,與之配套的NPS版本為0.26.10。"
def read_output(process, output_element):
"""
讀取子進程的輸出並將其傳遞給GUI線程顯示的函數
"""
for line in process.stdout:
output_element.print(line.strip())
for line in process.stderr:
output_element.print(line.strip())
# 定義GUI佈局
layout = [
[sg.Menu([['關於', ['本程序介紹','版本號', '作者']]])],
[sg.Text("服務端地址(IP):"), sg.Input(default_text="nps.qiaoyukeji.cn",key="-ADDRESS-")],
[sg.Text("服務端端口號:"), sg.Input(default_text="28024",key="-PORT-")],
[sg.Text("驗證密鑰(vkey):"), sg.Input(key="-VKEY-")],
[sg.Text("連接方式:"), sg.Input(default_text="tcp",key="-TYPE-")],
[sg.Button("連接遠程穿透服務器"), sg.Button("退出")],
[sg.Output(size=(60, 10), key="-OUTPUT-")]
]
# 創建窗口
window = sg.Window("NPS內網穿透GUI工具(v0.0.1)", layout)
output_element = window["-OUTPUT-"]
# 事件循環
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED or event == "退出":
break
if event == "連接遠程穿透服務器":
address = values["-ADDRESS-"]
port = values["-PORT-"]
vkey = values["-VKEY-"]
type = values["-TYPE-"]
command = f"npc.exe -server={address}:{port} -vkey={vkey} -type={type}"
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
bufsize=1,
startupinfo=startupinfo,
creationflags=subprocess.CREATE_NO_WINDOW
)
# 創建線程讀取子進程輸出並傳遞給GUI線程顯示
output_thread = threading.Thread(target=read_output, args=(process, output_element), daemon=True)
output_thread.start()
if event == "版本號":
sg.popup(f"版本號: {version}")
if event == "作者":
sg.popup(f"作者: {author}")
if event == "本程序介紹":
sg.popup(f"{about_me}")
# 關閉窗口
window.close()
目錄下輸入 python main.py 運行程序,程序的運行圖如下所示。
填寫好自己的 nps 服務端的 網址(IP)、端口、驗證密鑰(vkey)與連接方式,點擊連接顯示連接成功。
至此,python 代碼版的 nps 客户端 GUI 程序已完成。
2.3 python 程序轉 exe 程序
python 版的程序雖然已經完成,但是需要電腦先安裝 python 運行環境,並且安裝對應的 python 庫,之後運行 python 代碼才能正真的運行起來程序,對於普通人來説過於麻煩與繁瑣了。
能不能打包成 exe 文件,無需安裝,雙擊就能運行呢?
答案是肯定的,就是使用 pyinstaller 。
PyInstaller 是一個用於將 Python 應用程序打包成可執行文件的工具。它可以將 Python 腳本及其依賴的庫、資源文件等打包成一個獨立的可執行文件,方便在沒有 Python 解釋器的環境中運行。
首先安裝使用 pip install pyinstaller 安裝 pyinstaller ;
之後在上面的目錄中運行 PyInstaller 打包程序;
pyinstaller --onefile --hidden-import PySimpleGUI main.py --name "NPS內網穿透客户端GUI程序" --noconsole
--onefile:指定生成一個單個的可執行文件,而不是生成一個文件夾包含多個文件。這意味着所有的依賴項將被打包到一個可執行文件中。
--hidden-import PySimpleGUI:指定需要導入的額外模塊或庫。在這個例子中,指定了需要導入PySimpleGUI庫,因為腳本"main.py"中使用了PySimpleGUI。這樣PyInstaller會確保將該庫包含在生成的可執行文件中。
main.py:要打包的Python腳本的文件名或路徑。在這個例子中,指定了"main.py"作為要打包的腳本。
--name "NPS內網穿透客户端GUI程序":指定生成的可執行文件的名稱。在這個例子中,指定了生成的可執行文件的名稱為"NPS內網穿透客户端GUI程序"。
--noconsole:指定生成的可執行文件在運行時不顯示控制枱窗口。這適用於圖形用户界面(GUI)應用程序,因為它們通常不需要顯示控制枱輸出。
上述打包程序就可以在目錄下生成一個 dist 目錄、將 main.py 打包成一個 exe 程序放置在 dist 目錄中,然後我們需要將 npc.exe 也複製一份到 dist 目錄中。
在 dist 目錄中雙擊 NPS內網穿透客户端GUI程序.exe 即可正常運行 NPS\_GUI 程序。
我們可以將 NPS內網穿透客户端GUI程序.exe 與 npc.exe 兩個文件打包成一個壓縮包發送給他人,他人無需安裝配置運行環境、僅需解壓縮後雙擊程序即可運行程序。
至此 nps 客户端程序 GUI 界面程序已全部完成。
3、總結
本教程已在 Gitee、Github中進行開源。
Gitee:https://gitee.com/qiaoyukeji/nps_gui
Github:https://github.com/qiaoyukeji/nps_gui
本教程使用的是 PySimpleGUI 繪製 GUI 界面,由於 PySimpleGUI 庫本身的問題,第一次使用會提示==填入授權碼==或者==選擇忽略跳過==。
授權碼 PySimpleGUI 官方免費提供,但需要註冊領取,填入註冊授權碼後可一直免費使用。
選擇忽略將導致 PySimpleGUI 繪製的程序將只能試用31天,註冊填入授權碼即可解決
本文首發於本人博客:https://blog.gitnote.cn/post/nps_gui/index.html
版權信息: CC BY-NC-SA 4.0 (自由轉載-非商用-相同方式共享-保持署名)