微信企业微信应用多开开源小软件
·
开源微信多开python代码,有兴趣小伙伴加工一下加入一些其他功能
"""
微信多开工具
支持Windows平台的微信电脑版多开
"""
import os
import sys
import subprocess
import winreg
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import threading
import time
import tempfile
class MultiAppLauncher:
def __init__(self):
self.wechat_path = self.find_wechat_path()
self.wxwork_path = self.find_wxwork_path()
self.custom_path = None
self.sandboxie_path = self.find_sandboxie()
def find_wechat_path(self):
"""自动查找微信安装路径"""
# 常见的微信安装路径(包括Weixin和WeChat)
common_paths = [
r"C:\Program Files\Tencent\Weixin\Weixin.exe",
r"C:\Program Files (x86)\Tencent\Weixin\Weixin.exe",
r"C:\Program Files\Tencent\WeChat\WeChat.exe",
r"C:\Program Files (x86)\Tencent\WeChat\WeChat.exe",
r"D:\Program Files\Tencent\Weixin\Weixin.exe",
r"D:\Program Files (x86)\Tencent\Weixin\Weixin.exe",
r"D:\Program Files\Tencent\WeChat\WeChat.exe",
r"D:\Program Files (x86)\Tencent\WeChat\WeChat.exe",
]
# 先检查常见路径
for path in common_paths:
if os.path.exists(path):
return path
# 尝试从注册表读取
try:
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
r"Software\Tencent\WeChat",
0,
winreg.KEY_READ)
install_path, _ = winreg.QueryValueEx(key, "InstallPath")
winreg.CloseKey(key)
wechat_exe = os.path.join(install_path, "WeChat.exe")
if os.path.exists(wechat_exe):
return wechat_exe
except:
pass
return None
def find_wxwork_path(self):
"""自动查找企业微信安装路径"""
# 常见的企业微信安装路径
common_paths = [
r"C:\Program Files (x86)\WXWork\WXWork.exe",
r"C:\Program Files\WXWork\WXWork.exe",
r"D:\Program Files (x86)\WXWork\WXWork.exe",
r"D:\Program Files\WXWork\WXWork.exe",
]
# 先检查常见路径
for path in common_paths:
if os.path.exists(path):
return path
# 尝试从注册表读取
try:
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
r"Software\Tencent\WXWork",
0,
winreg.KEY_READ)
install_path, _ = winreg.QueryValueEx(key, "InstallPath")
winreg.CloseKey(key)
wxwork_exe = os.path.join(install_path, "WXWork.exe")
if os.path.exists(wxwork_exe):
return wxwork_exe
except:
pass
return None
def find_sandboxie(self):
"""自动查找Sandboxie-Plus安装路径"""
common_paths = [
r"C:\Program Files\Sandboxie-Plus\Start.exe",
r"C:\Program Files (x86)\Sandboxie-Plus\Start.exe",
r"C:\Program Files\Sandboxie\Start.exe",
r"C:\Program Files (x86)\Sandboxie\Start.exe",
]
for path in common_paths:
if os.path.exists(path):
return path
return None
def download_sandboxie(self):
"""引导用户下载Sandboxie-Plus"""
import webbrowser
webbrowser.open('https://github.com/sandboxie-plus/Sandboxie/releases/latest')
return "https://github.com/sandboxie-plus/Sandboxie/releases/latest"
def launch_with_sandboxie(self, app_path, count=1):
"""使用Sandboxie启动多个应用实例"""
if not self.sandboxie_path:
raise FileNotFoundError("未找到Sandboxie,请先安装")
if not app_path or not os.path.exists(app_path):
raise FileNotFoundError("未找到应用程序路径")
launched = []
for i in range(count):
try:
# 使用不同的沙盒名称
sandbox_name = f"AppBox_{i+1}"
# Sandboxie命令格式: Start.exe /box:沙盒名 程序路径
subprocess.Popen(
[self.sandboxie_path, f"/box:{sandbox_name}", app_path],
creationflags=subprocess.DETACHED_PROCESS
)
launched.append(i + 1)
print(f"已在沙盒 {sandbox_name} 中启动实例 {i+1}")
time.sleep(2)
except Exception as e:
raise Exception(f"在沙盒中启动第{i+1}个实例失败: {str(e)}")
return launched
def launch_app(self, app_path, count=1, use_sandboxie=False):
"""启动指定数量的应用实例"""
if not app_path or not os.path.exists(app_path):
raise FileNotFoundError("未找到应用程序路径,请手动指定")
# 如果选择使用Sandboxie
if use_sandboxie:
return self.launch_with_sandboxie(app_path, count)
# 否则使用批处理脚本方法
app_name = os.path.basename(app_path)
launched = []
# 创建临时批处理文件
bat_content = f'@echo off\n'
for i in range(count):
bat_content += f'echo Launching {app_name} instance {i+1}...\n'
bat_content += f'cmd /c start "" "{app_path}"\n'
bat_content += 'timeout /t 5 /nobreak >nul\n'
bat_content += 'echo All instances launched!\n'
# 写入临时批处理文件
with tempfile.NamedTemporaryFile(mode='w', suffix='.bat', delete=False, encoding='gbk') as f:
bat_file = f.name
f.write(bat_content)
try:
# 执行批处理文件
process = subprocess.Popen(
[bat_file],
creationflags=subprocess.CREATE_NO_WINDOW,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# 等待批处理完成
process.wait(timeout=count * 3 + 10)
# 清理临时文件
try:
os.remove(bat_file)
except:
pass
return list(range(1, count + 1))
except subprocess.TimeoutExpired:
process.kill()
try:
os.remove(bat_file)
except:
pass
raise Exception("启动超时")
except Exception as e:
try:
os.remove(bat_file)
except:
pass
raise Exception(f"启动失败: {str(e)}")
class MultiAppLauncherGUI:
def __init__(self, root):
self.root = root
self.root.title("应用多开工具 - 集成 Sandboxie")
self.root.geometry("580x590")
self.root.resizable(False, False)
self.launcher = MultiAppLauncher()
self.setup_ui()
def setup_ui(self):
"""设置界面"""
# 标题
title_frame = tk.Frame(self.root, bg="#07c160", height=60)
title_frame.pack(fill=tk.X)
title_frame.pack_propagate(False)
title_label = tk.Label(
title_frame,
text="应用多开工具",
font=("Microsoft YaHei UI", 18, "bold"),
bg="#07c160",
fg="white"
)
title_label.pack(pady=15)
# 主内容区
main_frame = tk.Frame(self.root, padx=30, pady=20)
main_frame.pack(fill=tk.BOTH, expand=True)
# 模式选择
mode_frame = tk.Frame(main_frame)
mode_frame.pack(fill=tk.X, pady=10)
tk.Label(mode_frame, text="启动模式:", font=("Microsoft YaHei UI", 10, "bold")).pack(anchor=tk.W)
mode_radio_frame = tk.Frame(mode_frame)
mode_radio_frame.pack(fill=tk.X, pady=5)
self.mode_var = tk.StringVar(value="wechat")
tk.Radiobutton(
mode_radio_frame,
text="微信",
variable=self.mode_var,
value="wechat",
font=("Microsoft YaHei UI", 9),
command=self.on_mode_change
).pack(side=tk.LEFT, padx=(0, 15))
tk.Radiobutton(
mode_radio_frame,
text="企业微信",
variable=self.mode_var,
value="wxwork",
font=("Microsoft YaHei UI", 9),
command=self.on_mode_change
).pack(side=tk.LEFT, padx=(0, 15))
tk.Radiobutton(
mode_radio_frame,
text="自定义软件",
variable=self.mode_var,
value="custom",
font=("Microsoft YaHei UI", 9),
command=self.on_mode_change
).pack(side=tk.LEFT)
# 应用路径
path_frame = tk.Frame(main_frame)
path_frame.pack(fill=tk.X, pady=10)
self.path_label = tk.Label(path_frame, text="微信路径:", font=("Microsoft YaHei UI", 10))
self.path_label.pack(anchor=tk.W)
path_input_frame = tk.Frame(path_frame)
path_input_frame.pack(fill=tk.X, pady=5)
self.path_var = tk.StringVar(value=self.launcher.wechat_path or "未找到微信路径")
self.path_entry = tk.Entry(
path_input_frame,
textvariable=self.path_var,
font=("Microsoft YaHei UI", 9),
state="readonly"
)
self.path_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
self.browse_btn = tk.Button(
path_input_frame,
text="浏览",
command=self.browse_app,
font=("Microsoft YaHei UI", 9),
bg="#f0f0f0"
)
self.browse_btn.pack(side=tk.RIGHT)
# 开启数量
count_frame = tk.Frame(main_frame)
count_frame.pack(fill=tk.X, pady=10)
tk.Label(count_frame, text="开启数量:", font=("Microsoft YaHei UI", 10)).pack(anchor=tk.W)
count_input_frame = tk.Frame(count_frame)
count_input_frame.pack(fill=tk.X, pady=5)
self.count_var = tk.IntVar(value=2)
self.count_spinbox = tk.Spinbox(
count_input_frame,
from_=1,
to=10,
textvariable=self.count_var,
font=("Microsoft YaHei UI", 10),
width=10
)
self.count_spinbox.pack(side=tk.LEFT)
tk.Label(
count_input_frame,
text="(建议不超过5个)",
font=("Microsoft YaHei UI", 8),
fg="gray"
).pack(side=tk.LEFT, padx=10)
# Sandboxie选项
sandbox_frame = tk.Frame(main_frame)
sandbox_frame.pack(fill=tk.X, pady=10)
self.use_sandboxie_var = tk.BooleanVar(value=False)
sandboxie_check_frame = tk.Frame(sandbox_frame)
sandboxie_check_frame.pack(fill=tk.X)
self.sandboxie_check = tk.Checkbutton(
sandboxie_check_frame,
text="使用 Sandboxie 沙盒启动(企业微信推荐)",
variable=self.use_sandboxie_var,
font=("Microsoft YaHei UI", 9),
command=self.on_sandboxie_change
)
self.sandboxie_check.pack(side=tk.LEFT)
# Sandboxie状态和下载按钮
self.sandboxie_status_frame = tk.Frame(sandbox_frame)
self.sandboxie_status_frame.pack(fill=tk.X, pady=3)
if self.launcher.sandboxie_path:
self.sandboxie_status_label = tk.Label(
self.sandboxie_status_frame,
text=f"✓ 已安装: {self.launcher.sandboxie_path}",
font=("Microsoft YaHei UI", 8),
fg="green"
)
else:
self.sandboxie_status_label = tk.Label(
self.sandboxie_status_frame,
text="✗ 未安装 Sandboxie-Plus",
font=("Microsoft YaHei UI", 8),
fg="red"
)
self.sandboxie_status_label.pack(side=tk.LEFT)
if not self.launcher.sandboxie_path:
self.download_btn = tk.Button(
self.sandboxie_status_frame,
text="自动安装",
command=self.auto_install_sandboxie,
font=("Microsoft YaHei UI", 8),
bg="#28a745",
fg="white",
cursor="hand2"
)
self.download_btn.pack(side=tk.LEFT, padx=5)
self.manual_download_btn = tk.Button(
self.sandboxie_status_frame,
text="手动下载",
command=self.download_sandboxie,
font=("Microsoft YaHei UI", 8),
bg="#0078d4",
fg="white",
cursor="hand2"
)
self.manual_download_btn.pack(side=tk.LEFT, padx=5)
# 启动按钮
btn_frame = tk.Frame(main_frame)
btn_frame.pack(pady=20)
self.launch_btn = tk.Button(
btn_frame,
text="启动应用",
command=self.launch_threaded,
font=("Microsoft YaHei UI", 12, "bold"),
bg="#07c160",
fg="white",
activebackground="#06ad56",
activeforeground="white",
width=20,
height=2,
cursor="hand2",
relief=tk.FLAT
)
self.launch_btn.pack()
# 状态栏
self.status_var = tk.StringVar(value="就绪")
status_label = tk.Label(
main_frame,
textvariable=self.status_var,
font=("Microsoft YaHei UI", 9),
fg="gray"
)
status_label.pack(pady=5)
# 提示信息
self.tip_var = tk.StringVar(value="提示:每个微信窗口需要单独扫码登录")
tip_label = tk.Label(
main_frame,
textvariable=self.tip_var,
font=("Microsoft YaHei UI", 8),
fg="orange",
wraplength=450,
justify=tk.LEFT
)
tip_label.pack(pady=5)
# 作者信息区域
author_frame = tk.Frame(self.root, bg="#f8f9fa", height=40)
author_frame.pack(side=tk.BOTTOM, fill=tk.X)
author_frame.pack_propagate(False)
author_content = tk.Frame(author_frame, bg="#f8f9fa")
author_content.pack(expand=True)
tk.Label(
author_content,
text="作者:",
font=("Microsoft YaHei UI", 8),
bg="#f8f9fa",
fg="#6c757d"
).pack(side=tk.LEFT, padx=5)
homepage_link = tk.Label(
author_content,
text="主页",
font=("Microsoft YaHei UI", 8, "underline"),
bg="#f8f9fa",
fg="#007bff",
cursor="hand2"
)
homepage_link.pack(side=tk.LEFT, padx=3)
homepage_link.bind("<Button-1>", lambda e: self.open_url("https://xoxome.online"))
tk.Label(
author_content,
text="|",
font=("Microsoft YaHei UI", 8),
bg="#f8f9fa",
fg="#6c757d"
).pack(side=tk.LEFT, padx=3)
email_link = tk.Label(
author_content,
text="邮箱系统",
font=("Microsoft YaHei UI", 8, "underline"),
bg="#f8f9fa",
fg="#007bff",
cursor="hand2"
)
email_link.pack(side=tk.LEFT, padx=3)
email_link.bind("<Button-1>", lambda e: self.open_url("https://mail.xoxome.online"))
def open_url(self, url):
"""打开URL链接"""
import webbrowser
try:
webbrowser.open(url)
except Exception as e:
messagebox.showerror("错误", f"无法打开链接:{str(e)}")
def on_mode_change(self):
"""模式切换时的处理"""
mode = self.mode_var.get()
if mode == "wechat":
self.path_label.config(text="微信路径:")
if self.launcher.wechat_path:
self.path_var.set(self.launcher.wechat_path)
else:
self.path_var.set("未找到微信路径")
self.tip_var.set("提示:每个微信窗口需要单独扫码登录")
elif mode == "wxwork":
self.path_label.config(text="企业微信路径:")
if self.launcher.wxwork_path:
self.path_var.set(self.launcher.wxwork_path)
else:
self.path_var.set("未找到企业微信路径")
self.tip_var.set("⚠️ 企业微信批处理方法只能多进程,无法多窗口\n✅ 建议勾选 [使用Sandboxie] 实现真正的多窗口")
else: # custom
self.path_label.config(text="应用路径:")
if self.launcher.custom_path:
self.path_var.set(self.launcher.custom_path)
else:
self.path_var.set("请选择要多开的应用程序")
self.tip_var.set("提示:选择任意.exe程序,支持大部分应用多开\n某些应用可能有单实例保护,多开效果因软件而异")
def on_sandboxie_change(self):
"""Sandboxie选项变化时的处理"""
if self.use_sandboxie_var.get() and not self.launcher.sandboxie_path:
messagebox.showwarning(
"提示",
"您尚未安装 Sandboxie-Plus。\n\n点击\"下载 Sandboxie-Plus\"按钮进行安装。"
)
self.use_sandboxie_var.set(False)
def auto_install_sandboxie(self):
"""自动安装Sandboxie-Plus"""
result = messagebox.askquestion(
"自动安装 Sandboxie-Plus",
"即将自动下载并安装 Sandboxie-Plus。\n\n"
"过程包括:\n"
"1. 从GitHub下载最新版本\n"
"2. 自动运行安装程序(需要管理员权限)\n"
"3. 安装完成后重启本程序\n\n"
"是否继续?",
icon='question'
)
if result == 'yes':
try:
# 运行自动安装脚本
subprocess.Popen(
[sys.executable, 'auto_install_sandboxie.py'],
creationflags=subprocess.CREATE_NEW_CONSOLE
)
messagebox.showinfo(
"提示",
"已启动自动安装程序。\n\n"
"请在新窗口中完成安装,\n"
"安装完成后重启本程序即可使用。"
)
except Exception as e:
messagebox.showerror("错误", f"启动安装程序失败:{str(e)}")
def download_sandboxie(self):
"""手动下载Sandboxie-Plus"""
try:
url = self.launcher.download_sandboxie()
messagebox.showinfo(
"手动下载 Sandboxie-Plus",
f"即将打开下载页面:\n{url}\n\n"
"请下载并安装后重启本程序。\n\n"
"安装建议:\n"
"1. 下载 Sandboxie-Plus-x64-vX.X.X.exe\n"
"2. 以管理员身份运行安装程序\n"
"3. 安装完成后重启本程序"
)
except Exception as e:
messagebox.showerror("错误", f"打开浏览器失败:{str(e)}")
def browse_app(self):
"""浏览选择应用程序路径"""
mode = self.mode_var.get()
if mode == "wechat":
title = "选择微信程序"
initialdir = "C:\\Program Files\\Tencent"
elif mode == "wxwork":
title = "选择企业微信程序"
initialdir = "C:\\Program Files (x86)\\WXWork"
else:
title = "选择要多开的应用程序"
initialdir = "C:\\Program Files"
filename = filedialog.askopenfilename(
title=title,
filetypes=[("可执行文件", "*.exe"), ("所有文件", "*.*")],
initialdir=initialdir
)
if filename:
if mode == "wechat":
self.launcher.wechat_path = filename
elif mode == "wxwork":
self.launcher.wxwork_path = filename
else:
self.launcher.custom_path = filename
self.path_var.set(filename)
def launch_threaded(self):
"""在新线程中启动应用(避免界面卡顿)"""
thread = threading.Thread(target=self.launch_app)
thread.daemon = True
thread.start()
def launch_app(self):
"""启动应用"""
try:
self.launch_btn.config(state=tk.DISABLED)
count = self.count_var.get()
mode = self.mode_var.get()
if count < 1 or count > 10:
messagebox.showerror("错误", "开启数量必须在1-10之间")
return
# 根据模式选择路径
if mode == "wechat":
app_path = self.launcher.wechat_path
app_name = "微信"
elif mode == "wxwork":
app_path = self.launcher.wxwork_path
app_name = "企业微信"
else:
app_path = self.launcher.custom_path
if app_path:
app_name = os.path.basename(app_path).replace(".exe", "")
else:
app_name = "应用"
if not app_path:
messagebox.showerror("错误", f"请先选择{app_name}的路径")
return
use_sandboxie = self.use_sandboxie_var.get()
if use_sandboxie:
self.status_var.set(f"正在通过 Sandboxie 启动 {count} 个{app_name}实例...")
else:
self.status_var.set(f"正在启动 {count} 个{app_name}实例...")
self.launcher.launch_app(app_path, count, use_sandboxie)
if use_sandboxie:
self.status_var.set(f"成功在沙盒中启动 {count} 个{app_name}实例")
messagebox.showinfo(
"成功",
f"已成功在 Sandboxie 沙盒中启动 {count} 个{app_name}窗口!\n\n"
f"每个实例运行在独立的沙盒中:\n"
f"AppBox_1, AppBox_2, AppBox_3...\n\n"
f"可以在 Sandboxie 控制面板中查看和管理。"
)
else:
self.status_var.set(f"成功启动 {count} 个{app_name}实例")
messagebox.showinfo("成功", f"已成功启动 {count} 个{app_name}窗口!")
except FileNotFoundError as e:
self.status_var.set("启动失败")
messagebox.showerror("错误", str(e))
except Exception as e:
self.status_var.set("启动失败")
messagebox.showerror("错误", f"启动失败:{str(e)}")
finally:
self.launch_btn.config(state=tk.NORMAL)
def main():
root = tk.Tk()
app = MultiAppLauncherGUI(root)
root.mainloop()
if __name__ == "__main__":
main()
https://github.com/robert1281/wechat-
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)