import os
import sys
import subprocess
import re
import requests
import tempfile
import platform
from bs4 import BeautifulSoup
import winregclass VCRedistManager:def __init__(self):self.supported_versions = {"2005": {"x86": "https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.exe","x64": "https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.exe"},"2008": {"x86": "https://download.microsoft.com/download/d/2/4/d242c3fb-da5a-4542-ad66-f9661d0a8d19/vcredist_x86.exe","x64": "https://download.microsoft.com/download/d/2/4/d242c3fb-da5a-4542-ad66-f9661d0a8d19/vcredist_x64.exe"},"2010": {"x86": "https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe","x64": "https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe"},"2013": {"x86": "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x86.exe","x64": "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe"},"2015-2022": {"x86": "https://aka.ms/vs/17/release/vc_redist.x86.exe","x64": "https://aka.ms/vs/17/release/vc_redist.x64.exe","arm64": "https://aka.ms/vs/17/release/vc_redist.arm64.exe"}}# 检查是否在Windows系统上运行if platform.system() != "Windows":print("错误: 此工具仅适用于Windows系统")sys.exit(1)# 检查是否以管理员权限运行self.is_admin = self.check_admin()if not self.is_admin:print("警告: 建议以管理员权限运行此程序以确保安装功能正常工作")def check_admin(self):"""检查程序是否以管理员权限运行"""try:return os.getuid() == 0except AttributeError:import ctypesreturn ctypes.windll.shell32.IsUserAnAdmin() != 0def get_installed_versions(self):"""获取系统中已安装的VC++版本"""installed = {}# 检查注册表中的已安装程序reg_paths = [r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"]for reg_path in reg_paths:try:key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_path)i = 0while True:try:subkey_name = winreg.EnumKey(key, i)subkey = winreg.OpenKey(key, subkey_name)# 尝试获取显示名称try:display_name = winreg.QueryValueEx(subkey, "DisplayName")[0]# 检测VC++ redistributablevc_pattern = re.compile(r'Visual C\+\+ \d+ Redistributable(?: \(x86\)|\(x64\)|\(ARM64\))?')if vc_pattern.search(display_name):# 提取版本信息version_match = re.search(r'\d{4}', display_name)arch_match = re.search(r'(x86|x64|ARM64)', display_name)if version_match:version = version_match.group()# 特殊处理2015-2022版本if version == "2015" or version == "2017" or version == "2019" or version == "2022":version = "2015-2022"arch = arch_match.group().lower() if arch_match else "unknown"if version not in installed:installed[version] = set()installed[version].add(arch)except WindowsError:passwinreg.CloseKey(subkey)i += 1except WindowsError:breakwinreg.CloseKey(key)except WindowsError:pass# 转换集合为列表以便于处理for version in installed:installed[version] = list(installed[version])return installeddef display_installed_versions(self, installed_versions):"""显示已安装的VC++版本"""print("\n已安装的Microsoft Visual C++ Redistributable版本:")if not installed_versions:print(" 未检测到已安装的VC++ Redistributable版本")returnfor version in sorted(installed_versions.keys()):arches = ", ".join(installed_versions[version])print(f" {version} - 架构: {arches}")def check_missing_versions(self, installed_versions):"""检查缺失的VC++版本"""missing = {}for version, arches in self.supported_versions.items():if version not in installed_versions:# 整个版本都缺失missing[version] = list(arches.keys())else:# 检查该版本下缺失的架构installed_arches = installed_versions[version]for arch in arches.keys():if arch not in installed_arches:if version not in missing:missing[version] = []missing[version].append(arch)return missingdef display_missing_versions(self, missing_versions):"""显示缺失的VC++版本"""print("\n缺失的Microsoft Visual C++ Redistributable版本:")if not missing_versions:print(" 没有检测到缺失的VC++ Redistributable版本")returnfor version in sorted(missing_versions.keys()):arches = ", ".join(missing_versions[version])print(f" {version} - 架构: {arches}")def download_and_install(self, version, arch):"""下载并安装指定版本和架构的VC++ redistributable"""if version not in self.supported_versions or arch not in self.supported_versions[version]:print(f"错误: 不支持的VC++版本 {version} 或架构 {arch}")return Falseurl = self.supported_versions[version][arch]print(f"\n正在下载 {version} {arch} 版本...")try:# 创建临时文件with tempfile.NamedTemporaryFile(suffix=".exe", delete=False) as tmp_file:response = requests.get(url, stream=True)response.raise_for_status()# 下载文件total_size = int(response.headers.get('content-length', 0))downloaded_size = 0for chunk in response.iter_content(chunk_size=8192):if chunk:tmp_file.write(chunk)downloaded_size += len(chunk)progress = (downloaded_size / total_size) * 100 if total_size > 0 else 0print(f"下载进度: {progress:.1f}%", end='\r')installer_path = tmp_file.nameprint("\n下载完成,准备安装...")# 运行安装程序print(f"正在安装 {version} {arch} 版本...")subprocess.run([installer_path, "/quiet", "/norestart"], check=True)print(f"{version} {arch} 版本安装完成")# 清理临时文件try:os.unlink(installer_path)except:passreturn Trueexcept Exception as e:print(f"安装过程出错: {str(e)}")return Falsedef install_missing(self, missing_versions, select_all=False):"""安装缺失的VC++版本"""if not missing_versions:print("没有需要安装的缺失版本")returnfor version in sorted(missing_versions.keys()):arches = missing_versions[version]for arch in arches:if not select_all:response = input(f"是否安装 {version} {arch} 版本? (y/n): ")if response.lower() not in ['y', 'yes']:continueself.download_and_install(version, arch)def run(self):"""运行VC++ Redistributable管理工具"""print("="*50)print("Microsoft Visual C++ Redistributable 管理工具")print("="*50)while True:print("\n请选择操作:")print("1. 检查已安装的VC++版本")print("2. 检查并安装缺失的VC++版本")print("3. 安装所有支持的VC++版本")print("4. 退出")choice = input("请输入选项 (1-4): ")if choice == '1':installed = self.get_installed_versions()self.display_installed_versions(installed)elif choice == '2':installed = self.get_installed_versions()self.display_installed_versions(installed)missing = self.check_missing_versions(installed)self.display_missing_versions(missing)if missing:self.install_missing(missing)elif choice == '3':confirm = input("确定要安装所有支持的VC++版本吗? 这可能需要一些时间和磁盘空间。(y/n): ")if confirm.lower() in ['y', 'yes']:# 创建一个包含所有版本和架构的"缺失"字典all_versions = {v: list(a.keys()) for v, a in self.supported_versions.items()}self.install_missing(all_versions, select_all=True)elif choice == '4':print("感谢使用,再见!")breakelse:print("无效的选项,请重试")if __name__ == "__main__":try:manager = VCRedistManager()manager.run()except Exception as e:print(f"程序出错: {str(e)}")sys.exit(1)