1、问题来源

本人之前撰写过一个 使用nps搭建内网穿透并配置泛域名解析的教程,但其中的运行客户端程序使用的是 CMD 命令行进行操作,并且需要配置的参数较多,总是记不住。

构建NPS内网穿透服务客户端GUI界面

所以就在考虑是否能将 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内网穿透服务客户端GUI界面

填写好自己的 nps 服务端的 网址(IP)、端口、验证密钥(vkey)与连接方式,点击连接显示连接成功。

构建NPS内网穿透服务客户端GUI界面

至此,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 目录中。

构建NPS内网穿透服务客户端GUI界面
dist 目录中双击 NPS内网穿透客户端GUI程序.exe 即可正常运行 NPS_GUI 程序。

我们可以将 NPS内网穿透客户端GUI程序.exenpc.exe 两个文件打包成一个压缩包发送给他人,他人无需安装配置运行环境、仅需解压缩后双击程序即可运行程序。

至此 nps 客户端程序 GUI 界面程序已全部完成。

3、总结

本教程已在 Gitee、Github中进行开源。 Gitee:gitee.com/qiaoyukeji/… Github:github.com/qiaoyukeji/…

本教程使用的是 PySimpleGUI 绘制 GUI 界面,由于 PySimpleGUI 库本身的问题,第一次使用会提示==填入授权码==或者==选择忽略跳过==。 授权码 PySimpleGUI 官方免费提供,但需要注册领取,填入注册授权码后可一直免费使用。 选择忽略将导致 PySimpleGUI 绘制的程序将只能试用31天,注册填入授权码即可解决


本文首发于本人博客:blog.gitnote.cn/post/nps_gu…

版权信息: CC BY-NC-SA 4.0 (自由转载-非商用-相同方式共享-保持署名)