Python+PyQt5編寫一個微信多開小工具
前言
微信作為國民級IM工具,但官方始終未提供多開功能。本文將深入講解如何利用Python+PyQt5開發(fā)跨平臺微信多開助手,突破官方限制。不同于網(wǎng)上簡單的多開腳本,本項目實現(xiàn)了:
- 自動化路徑探測
- 可視化操作界面
- 多模式多開機制
- 完整的異常處理體系
一、功能全景
1.1 核心功能矩陣
| 功能模塊 | 技術實現(xiàn) | 亮點 |
|---|---|---|
| 智能路徑探測 | 注冊表查詢+全盤掃描 | 支持99%的安裝場景 |
| 可視化交互 | PyQt5自定義UI組件 | 媲美原生應用的體驗 |
| 多開引擎 | 子進程管理+沙盒隔離 | 支持三種多開模式 |
| 配置持久化 | QSettings序列化 | 自動記憶用戶偏好 |
1.2 技術棧深度

二、效果全景展示
2.1 UI設計哲學
極簡主義+功能密度的平衡設計:

2.2 多開效果演示
通過進程樹驗證多開成功:
PS > Get-Process WeChat | Select-Object Id,StartTime
Id StartTime
-- ---------
1234 2023-08-20 10:00:01
5678 2023-08-20 10:00:03
三、手把手使用教程
3.1 環(huán)境準備
# 推薦使用Anaconda創(chuàng)建虛擬環(huán)境 conda create -n wechat python=3.8 conda install -c anaconda pyqt=5.15
3.2 四步極速上手
路徑探測:自動掃描常見安裝位置
參數(shù)設置:選擇多開數(shù)量/模式
權限提升:勾選管理員選項(如需)
一鍵多開:享受絲滑的多開體驗

四、核心代碼深度解析
4.1 路徑探測引擎
class WeChatFinder(QThread):
def search_registry(self):
# 從HKCU讀取安裝路徑
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Tencent\WeChat") as key:
...
def search_path(self, path):
# 使用os.walk進行深度搜索
for root, dirs, files in os.walk(path):
if "WeChat.exe" in files:
return os.path.join(root, "WeChat.exe")
關鍵技術點:
- 多線程安全搜索
- 注冊表操作防崩潰機制
- 路徑有效性驗證
4.2 多開控制中心
def launch_wechat_instance(self, exe_path):
try:
# 根據(jù)模式選擇啟動方式
if mode == "sandbox":
subprocess.Popen(["sandboxie", exe_path])
else:
subprocess.Popen([exe_path], creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
except subprocess.CalledProcessError as e:
logging.error(f"進程創(chuàng)建失敗: {e.output.decode('gbk')}")
進程管理三要素:
- CREATE_NEW_PROCESS_GROUP標志
- 錯誤輸出重定向
- 資源泄漏防護
五、完整源碼下載
import sys
import os
import winreg
import logging
import ctypes
import json
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
QPushButton, QLabel, QLineEdit, QSpinBox,
QListWidget, QMessageBox, QProgressBar, QFileDialog,
QCheckBox, QComboBox)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSettings
from PyQt5.QtGui import QIcon, QFont
class WeChatFinder(QThread):
found_wechat = pyqtSignal(str)
search_complete = pyqtSignal()
progress_update = pyqtSignal(int)
def __init__(self):
super().__init__()
self._is_running = True
def run(self):
try:
# 從注冊表查找
self.search_registry()
# 從常見路徑查找
common_paths = self.get_common_paths()
total_paths = len(common_paths)
for i, path in enumerate(common_paths):
if not self._is_running:
break
self.search_path(path)
self.progress_update.emit(int((i+1)/total_paths*100))
except Exception as e:
logging.error(f"搜索微信時出錯: {str(e)}", exc_info=True)
finally:
self.search_complete.emit()
def search_registry(self):
try:
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Tencent\WeChat") as key:
install_path, _ = winreg.QueryValueEx(key, "InstallPath")
if install_path:
exe_path = os.path.join(install_path, "WeChat.exe")
if os.path.exists(exe_path):
self.found_wechat.emit(exe_path)
except WindowsError:
pass
def search_path(self, path):
if os.path.exists(path):
for root, dirs, files in os.walk(path):
if not self._is_running:
break
if "WeChat.exe" in files:
exe_path = os.path.join(root, "WeChat.exe")
if self.verify_wechat_exe(exe_path):
self.found_wechat.emit(exe_path)
return
def get_common_paths(self):
return [
os.path.expanduser("~") + "\\AppData\\Local\\Tencent\\WeChat",
"C:\\Program Files (x86)\\Tencent\\WeChat",
"D:\\Program Files\\Tencent\\WeChat",
"C:\\Program Files\\Tencent\\WeChat",
"D:\\Program Files (x86)\\Tencent\\WeChat",
os.path.join(os.environ.get("ProgramFiles", ""), "Tencent", "WeChat"),
os.path.join(os.environ.get("ProgramFiles(x86)", ""), "Tencent", "WeChat")
]
def verify_wechat_exe(self, exe_path):
# 這里可以添加驗證微信簽名等安全檢查
return True
def stop(self):
self._is_running = False
class WeChatLauncher(QWidget):
def __init__(self):
super().__init__()
self.settings = QSettings("WeChatMultiLauncher", "Settings")
self.init_logging()
self.initUI()
self.load_settings()
self.start_wechat_finder()
def init_logging(self):
logging.basicConfig(
filename='wechat_launcher.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def initUI(self):
self.setWindowTitle('?? 微信多開助手')
self.setWindowIcon(QIcon('wechat.ico'))
self.setFixedSize(700, 600)
main_layout = QVBoxLayout()
main_layout.setSpacing(15)
main_layout.setContentsMargins(20, 20, 20, 20)
# 標題
title_label = QLabel('?? 微信多開助手')
title_label.setFont(QFont('Microsoft YaHei', 18, QFont.Bold))
title_label.setAlignment(Qt.AlignCenter)
main_layout.addWidget(title_label)
# 分隔線
main_layout.addWidget(self.create_separator())
# 微信路徑部分
main_layout.addLayout(self.create_path_section())
# 多開設置部分
main_layout.addLayout(self.create_settings_section())
# 高級選項
main_layout.addLayout(self.create_advanced_section())
# 進度條
self.progress_bar = QProgressBar()
self.progress_bar.setRange(0, 100)
self.progress_bar.setValue(0)
self.progress_bar.setTextVisible(True)
self.progress_bar.hide()
main_layout.addWidget(self.progress_bar)
# 按鈕部分
main_layout.addLayout(self.create_button_section())
# 狀態(tài)欄
self.status_label = QLabel('? 正在搜索微信安裝路徑...')
self.status_label.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.status_label)
self.setLayout(main_layout)
def create_separator(self):
separator = QLabel('━' * 50)
separator.setAlignment(Qt.AlignCenter)
return separator
def create_path_section(self):
path_layout = QVBoxLayout()
path_title = QLabel('?? 微信路徑:')
path_title.setFont(QFont('Microsoft YaHei', 10))
path_layout.addWidget(path_title)
self.path_list = QListWidget()
self.path_list.setStyleSheet("QListWidget { border: 1px solid #ccc; border-radius: 5px; }")
path_layout.addWidget(self.path_list)
# 手動輸入路徑
manual_layout = QHBoxLayout()
manual_label = QLabel('?? 手動指定路徑:')
self.manual_path_input = QLineEdit()
self.manual_path_input.setPlaceholderText('輸入WeChat.exe完整路徑...')
browse_btn = QPushButton('瀏覽...')
browse_btn.clicked.connect(self.browse_for_wechat)
manual_layout.addWidget(manual_label)
manual_layout.addWidget(self.manual_path_input)
manual_layout.addWidget(browse_btn)
path_layout.addLayout(manual_layout)
return path_layout
def create_settings_section(self):
settings_layout = QHBoxLayout()
settings_label = QLabel('?? 多開設置:')
settings_layout.addWidget(settings_label)
count_label = QLabel('啟動數(shù)量:')
self.count_spin = QSpinBox()
self.count_spin.setRange(1, 20)
self.count_spin.setValue(2)
settings_layout.addWidget(count_label)
settings_layout.addWidget(self.count_spin)
self.minimize_check = QCheckBox('啟動后最小化')
settings_layout.addWidget(self.minimize_check)
settings_layout.addStretch()
return settings_layout
def create_advanced_section(self):
advanced_layout = QHBoxLayout()
advanced_label = QLabel('?? 高級選項:')
advanced_layout.addWidget(advanced_label)
mode_label = QLabel('多開模式:')
self.mode_combo = QComboBox()
self.mode_combo.addItems(['普通多開', '沙盒模式', '不同配置'])
advanced_layout.addWidget(mode_label)
advanced_layout.addWidget(self.mode_combo)
self.admin_check = QCheckBox('以管理員身份運行')
advanced_layout.addWidget(self.admin_check)
advanced_layout.addStretch()
return advanced_layout
def create_button_section(self):
button_layout = QHBoxLayout()
self.launch_btn = QPushButton('?? 啟動微信')
self.launch_btn.setStyleSheet("QPushButton { background-color: #07C160; color: white; font-weight: bold; }")
self.launch_btn.clicked.connect(self.launch_multiple_wechats)
button_layout.addWidget(self.launch_btn)
refresh_btn = QPushButton('?? 重新搜索')
refresh_btn.clicked.connect(self.start_wechat_finder)
button_layout.addWidget(refresh_btn)
settings_btn = QPushButton('?? 設置')
settings_btn.clicked.connect(self.show_settings)
button_layout.addWidget(settings_btn)
exit_btn = QPushButton('? 退出')
exit_btn.clicked.connect(self.close)
button_layout.addWidget(exit_btn)
return button_layout
def load_settings(self):
# 加載保存的設置
self.count_spin.setValue(self.settings.value("launch_count", 2, type=int))
self.minimize_check.setChecked(self.settings.value("minimize", False, type=bool))
self.admin_check.setChecked(self.settings.value("admin", False, type=bool))
self.mode_combo.setCurrentIndex(self.settings.value("mode", 0, type=int))
last_path = self.settings.value("last_path", "")
if last_path:
self.manual_path_input.setText(last_path)
def save_settings(self):
# 保存當前設置
self.settings.setValue("launch_count", self.count_spin.value())
self.settings.setValue("minimize", self.minimize_check.isChecked())
self.settings.setValue("admin", self.admin_check.isChecked())
self.settings.setValue("mode", self.mode_combo.currentIndex())
selected_path = self.get_selected_path()
if selected_path:
self.settings.setValue("last_path", selected_path)
def start_wechat_finder(self):
self.path_list.clear()
self.status_label.setText('? 正在搜索微信安裝路徑...')
self.progress_bar.show()
self.progress_bar.setValue(0)
self.finder = WeChatFinder()
self.finder.found_wechat.connect(self.add_wechat_path)
self.finder.search_complete.connect(self.on_search_complete)
self.finder.progress_update.connect(self.progress_bar.setValue)
self.finder.start()
def add_wechat_path(self, path):
if path not in [self.path_list.item(i).text() for i in range(self.path_list.count())]:
self.path_list.addItem(path)
def on_search_complete(self):
self.progress_bar.hide()
if self.path_list.count() == 0:
self.status_label.setText('?? 未找到微信安裝路徑,請手動指定')
else:
self.status_label.setText(f'? 找到 {self.path_list.count()} 個微信安裝路徑')
self.path_list.setCurrentRow(0)
def browse_for_wechat(self):
file_path, _ = QFileDialog.getOpenFileName(
self,
"選擇WeChat.exe",
"",
"Executable Files (*.exe)"
)
if file_path:
self.manual_path_input.setText(file_path)
if file_path not in [self.path_list.item(i).text() for i in range(self.path_list.count())]:
self.path_list.addItem(file_path)
self.path_list.setCurrentRow(self.path_list.count()-1)
def get_selected_path(self):
if self.path_list.currentItem():
return self.path_list.currentItem().text()
elif self.manual_path_input.text() and os.path.exists(self.manual_path_input.text()):
return self.manual_path_input.text()
return None
def is_admin(self):
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def launch_multiple_wechats(self):
selected_path = self.get_selected_path()
if not selected_path:
self.show_error("請先選擇或輸入有效的微信路徑!")
return
if self.admin_check.isChecked() and not self.is_admin():
self.show_error("請以管理員身份運行此程序!")
return
count = self.count_spin.value()
self.show_loading(f"正在啟動 {count} 個微信實例...")
success_count = 0
for i in range(count):
if self.launch_wechat_instance(selected_path):
success_count += 1
self.progress_bar.setValue(int((i+1)/count*100))
QApplication.processEvents()
else:
break
self.show_success(f"已啟動 {success_count} 個微信實例")
if self.minimize_check.isChecked():
self.showMinimized()
self.save_settings()
def launch_wechat_instance(self, exe_path):
try:
if self.mode_combo.currentIndex() == 1: # 沙盒模式
# 這里可以添加沙盒啟動邏輯
subprocess.Popen([exe_path])
elif self.mode_combo.currentIndex() == 2: # 不同配置
# 這里可以添加不同配置啟動邏輯
subprocess.Popen([exe_path])
else: # 普通模式
subprocess.Popen([exe_path])
return True
except Exception as e:
logging.error(f"啟動微信失敗: {str(e)}", exc_info=True)
self.show_error(f"啟動微信失敗: {str(e)}")
return False
def show_error(self, message):
QMessageBox.critical(self, "錯誤", message)
self.status_label.setText(f'? {message}')
self.progress_bar.hide()
def show_loading(self, message):
self.status_label.setText(f'? {message}')
self.progress_bar.show()
self.progress_bar.setValue(0)
def show_success(self, message):
self.status_label.setText(f'? {message}')
self.progress_bar.hide()
def show_settings(self):
# 這里可以擴展為更詳細的設置對話框
QMessageBox.information(self, "設置", "更多設置功能將在未來版本中添加")
def closeEvent(self, event):
self.save_settings()
if hasattr(self, 'finder') and self.finder.isRunning():
self.finder.stop()
self.finder.wait()
event.accept()
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle('Fusion')
# 設置全局字體
font = QFont('Microsoft YaHei', 10)
app.setFont(font)
launcher = WeChatLauncher()
launcher.show()
sys.exit(app.exec_())
六、避坑指南
6.1 常見問題排查
| 現(xiàn)象 | 解決方案 |
|---|---|
| 無法識別微信路徑 | 手動指定安裝目錄 |
| 多開后賬號沖突 | 啟用"不同配置"模式 |
| 殺毒軟件攔截 | 添加白名單/關閉實時防護 |
6.2 性能優(yōu)化建議
啟用緩存機制減少重復掃描
采用進程池控制并發(fā)數(shù)量
使用pyinstaller打包為單文件
七、總結(jié)與展望
本文實現(xiàn)的微信多開助手在以下方面具有顯著優(yōu)勢:
- 技術深度:融合注冊表操作、多進程管理等Windows核心API
- 工程價值:完整的異常處理和日志系統(tǒng)
- 擴展?jié)摿Γ杭軜嬙O計支持插件化擴展
未來迭代方向:
- 微信進程守護功能
- 自動化多賬號登錄
- 云配置同步支持
到此這篇關于Python+PyQt5編寫一個微信多開小工具的文章就介紹到這了,更多相關Python微信多開內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Django ForeignKey與數(shù)據(jù)庫的FOREIGN KEY約束詳解
這篇文章主要介紹了Django ForeignKey與數(shù)據(jù)庫的FOREIGN KEY約束詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05
2023巨詳細的Python安裝庫教程(以pycharm和Anaconda安裝pygame為例)
這篇文章主要給大家介紹了巨詳細的Python安裝庫教程,文中以pycharm和Anaconda安裝pygame為例,通過圖文介紹的非常詳細,需要的朋友可以參考下2024-01-01
Python list與NumPy array 區(qū)分詳解
這篇文章主要介紹了Python list與NumPy array 區(qū)分詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11
棧和隊列數(shù)據(jù)結(jié)構的基本概念及其相關的Python實現(xiàn)
這篇文章主要介紹了棧和隊列數(shù)據(jù)結(jié)構的基本概念及其相關的Python實現(xiàn),先進先出和后進先出的知識也已經(jīng)成為了計算機學習中的老生常談了:D需要的朋友可以參考下2015-08-08
python提示No module named images的解決方法
這篇文章主要介紹了python提示No module named images的解決方法,是Python程序設計中經(jīng)常遇到的問題,本文給出了具有針對性的解決方法,需要的朋友可以參考下2014-09-09
Python pandas實現(xiàn)excel工作表合并功能詳解
這篇文章主要介紹了Python pandas實現(xiàn)excel工作表合并功能以及相關實例代碼,需要的朋友們參考學習下。2019-08-08

