python
复制代码
import os
import sys
import subprocess
import re
import requests
import tempfile
import platform
from bs4 import BeautifulSoup
import winreg
class 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() == 0
except AttributeError:
import ctypes
return ctypes.windll.shell32.IsUserAnAdmin() != 0
def 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 = 0
while True:
try:
subkey_name = winreg.EnumKey(key, i)
subkey = winreg.OpenKey(key, subkey_name)
# 尝试获取显示名称
try:
display_name = winreg.QueryValueEx(subkey, "DisplayName")[0]
# 检测VC++ redistributable
vc_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:
pass
winreg.CloseKey(subkey)
i += 1
except WindowsError:
break
winreg.CloseKey(key)
except WindowsError:
pass
# 转换集合为列表以便于处理
for version in installed:
installed[version] = list(installed[version])
return installed
def display_installed_versions(self, installed_versions):
"""显示已安装的VC++版本"""
print("\n已安装的Microsoft Visual C++ Redistributable版本:")
if not installed_versions:
print(" 未检测到已安装的VC++ Redistributable版本")
return
for 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 missing
def display_missing_versions(self, missing_versions):
"""显示缺失的VC++版本"""
print("\n缺失的Microsoft Visual C++ Redistributable版本:")
if not missing_versions:
print(" 没有检测到缺失的VC++ Redistributable版本")
return
for 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 False
url = 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 = 0
for 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 0
print(f"下载进度: {progress:.1f}%", end='\r')
installer_path = tmp_file.name
print("\n下载完成,准备安装...")
# 运行安装程序
print(f"正在安装 {version} {arch} 版本...")
subprocess.run([installer_path, "/quiet", "/norestart"], check=True)
print(f"{version} {arch} 版本安装完成")
# 清理临时文件
try:
os.unlink(installer_path)
except:
pass
return True
except Exception as e:
print(f"安装过程出错: {str(e)}")
return False
def install_missing(self, missing_versions, select_all=False):
"""安装缺失的VC++版本"""
if not missing_versions:
print("没有需要安装的缺失版本")
return
for 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']:
continue
self.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("感谢使用,再见!")
break
else:
print("无效的选项,请重试")
if __name__ == "__main__":
try:
manager = VCRedistManager()
manager.run()
except Exception as e:
print(f"程序出错: {str(e)}")
sys.exit(1)