import os
import sys
import subprocess
import argparse
from tkinter import Tk, filedialog, messagebox
import tempfile
import shutil
def convert_to_exe(input_file, output_file=None, icon=None, onefile=True, windowed=True):
"""
将 .bat 或 .vbs 文件转换为 .exe 文件
参数:
input_file (str): 输入的 .bat 或 .vbs 文件路径
output_file (str, optional): 输出的 .exe 文件路径,默认为输入文件名但扩展名为 .exe
icon (str, optional): 可执行文件的图标路径
onefile (bool, optional): 是否打包为单个文件
windowed (bool, optional): 是否不显示控制台窗口
"""
# 检查输入文件是否存在
if not os.path.exists(input_file):
print(f"错误: 文件 '{input_file}' 不存在")
return False
# 确定文件类型
file_ext = os.path.splitext(input_file)[1].lower()
if file_ext not in ['.bat', '.vbs']:
print(f"错误: 不支持的文件类型 '{file_ext}',仅支持 .bat 和 .vbs 文件")
return False
# 确定输出文件名
if output_file is None:
output_file = os.path.splitext(input_file)[0] + '.exe'
# 创建临时目录
temp_dir = tempfile.mkdtemp()
try:
# 创建包装脚本
wrapper_file = os.path.join(temp_dir, 'wrapper.py')
with open(wrapper_file, 'w', encoding='utf-8') as f:
f.write(f'''
import subprocess
import sys
import os
# 获取当前脚本所在目录
script_dir = os.path.dirname(os.path.abspath(__file__))
# 构建要执行的脚本路径
bat_file = os.path.join(script_dir, '{os.path.basename(input_file)}')
# 复制原始脚本到临时目录
import shutil
shutil.copy2('{input_file}', bat_file)
# 执行脚本
if '{file_ext}' == '.bat':
result = subprocess.run([bat_file], shell=True, capture_output=True, text=True)
else:
result = subprocess.run(['cscript', bat_file], capture_output=True, text=True)
# 输出结果(如果不是windowed模式)
if not {windowed}:
print("执行结果:")
print(result.stdout)
print(result.stderr)
# 如果需要返回退出码,可以使用 sys.exit(result.returncode)
sys.exit(0)
''')
# 复制原始脚本到临时目录
shutil.copy2(input_file, os.path.join(temp_dir, os.path.basename(input_file)))
# 构建 PyInstaller 命令
cmd = ['pyinstaller', '--clean']
if onefile:
cmd.append('--onefile')
if windowed:
cmd.append('--windowed')
if icon and os.path.exists(icon):
cmd.extend(['--icon', icon])
cmd.extend(['--name', os.path.splitext(os.path.basename(output_file))[0]])
cmd.extend(['--distpath', os.path.dirname(output_file)])
cmd.extend(['--workpath', os.path.join(temp_dir, 'build')])
cmd.append(wrapper_file)
# 执行 PyInstaller 命令
print("正在转换文件...")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"错误: PyInstaller 执行失败")
print(result.stderr)
return False
print(f"转换成功! 输出文件: {output_file}")
return True
finally:
# 清理临时目录
shutil.rmtree(temp_dir, ignore_errors=True)
def main():
"""主函数,处理命令行参数和GUI交互"""
parser = argparse.ArgumentParser(description='将 .bat 或 .vbs 文件转换为 .exe 文件')
parser.add_argument('input_file', nargs='?', help='输入的 .bat 或 .vbs 文件路径')
parser.add_argument('-o', '--output', help='输出的 .exe 文件路径')
parser.add_argument('-i', '--icon', help='可执行文件的图标路径 (.ico)')
parser.add_argument('--multi-file', action='store_true', help='打包为多个文件而不是单个文件')
parser.add_argument('--console', action='store_true', help='显示控制台窗口')
parser.add_argument('--gui', action='store_true', help='使用图形界面')
args = parser.parse_args()
# 如果指定了GUI模式或没有提供命令行参数,则使用GUI
if args.gui or not args.input_file:
root = Tk()
root.withdraw() # 隐藏主窗口
input_file = filedialog.askopenfilename(
title="选择 .bat 或 .vbs 文件",
filetypes=[("批处理文件", "*.bat"), ("VBS文件", "*.vbs"), ("所有文件", "*.*")]
)
if not input_file:
messagebox.showinfo("信息", "未选择文件,程序退出")
return
output_file = filedialog.asksaveasfilename(
title="保存为 .exe 文件",
defaultextension=".exe",
filetypes=[("可执行文件", "*.exe"), ("所有文件", "*.*")]
)
if not output_file:
messagebox.showinfo("信息", "未指定输出文件,程序退出")
return
icon_file = filedialog.askopenfilename(
title="选择图标文件 (可选)",
filetypes=[("图标文件", "*.ico"), ("所有文件", "*.*")]
)
onefile = not messagebox.askyesno("选项", "是否打包为多个文件?")
windowed = not messagebox.askyesno("选项", "是否显示控制台窗口?")
if icon_file:
icon = icon_file
else:
icon = None
success = convert_to_exe(
input_file=input_file,
output_file=output_file,
icon=icon,
onefile=onefile,
windowed=windowed
)
if success:
messagebox.showinfo("成功", f"文件已成功转换为: {output_file}")
else:
messagebox.showerror("错误", "文件转换失败")
else:
# 使用命令行参数
convert_to_exe(
input_file=args.input_file,
output_file=args.output,
icon=args.icon,
onefile=not args.multi_file,
windowed=not args.console
)
if __name__ == "__main__":
main()
下载:https://wwcq.lanzouu.com/i7s9D2zdtqef 无密码,感谢支持。