驅動程式備份
-pnputil
import os
import subprocess
import threading
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
# 備份驅動程式
def backup_drivers(backup_dir):
# 如果備份目錄不存在,創建它
if not os.path.exists(backup_dir):
os.makedirs(backup_dir)
try:
command = f"pnputil /export-driver * {backup_dir}"
subprocess.run(command, shell=True, check=True)
messagebox.showinfo("成功", f"驅動程式備份成功!所有驅動已導出到 {backup_dir}")
except subprocess.CalledProcessError as e:
messagebox.showerror("錯誤", f"備份失敗,錯誤信息:{e}")
# 還原驅動程式
def restore_drivers(backup_dir):
if not os.path.exists(backup_dir):
messagebox.showerror("錯誤", f"備份目錄 {backup_dir} 不存在。")
return
try:
command = f"pnputil /add-driver {backup_dir}\\*.inf /subdirs /install"
subprocess.run(command, shell=True, check=True)
messagebox.showinfo("成功", "驅動程式還原成功!")
except subprocess.CalledProcessError as e:
messagebox.showerror("錯誤", f"還原失敗,錯誤信息:{e}")
# 啟動進度條並執行程序
def run_task_in_thread(task, backup_dir):
progress_bar.start() # 開始進度條滾動
task_thread = threading.Thread(target=lambda: run_task(task, backup_dir))
task_thread.start()
# 執行具體的備份或還原任務
def run_task(task, backup_dir):
try:
task(backup_dir) # 執行具體的備份或還原函數
finally:
progress_bar.stop() # 結束進度條滾動
# 選擇目錄
def select_directory():
path = filedialog.askdirectory()
if path:
entry_path.delete(0, tk.END)
entry_path.insert(0, path)
# 自訂圓角按鈕
def create_rounded_button(canvas, text, command, x, y, width, height, color):
# 圓角按鈕外框
button_rect = canvas.create_rectangle(x, y, x + width, y + height, outline=color, fill=color, width=2)
# 圓角
radius = 20
canvas.create_oval(x, y, x + radius, y + radius, outline=color, fill=color)
canvas.create_oval(x + width - radius, y, x + width, y + radius, outline=color, fill=color)
canvas.create_oval(x, y + height - radius, x + radius, y + height, outline=color, fill=color)
canvas.create_oval(x + width - radius, y + height - radius, x + width, y + height, outline=color, fill=color)
# 按鈕文字
canvas.create_text(x + width / 2, y + height / 2, text=text, font=("Arial", 14), fill="black")
# 綁定點擊事件
canvas.tag_bind(button_rect, "<Button-1>", lambda e: command())
canvas.tag_bind(canvas.create_text(x + width / 2, y + height / 2, text=text, font=("Arial", 14), fill="black"), "<Button-1>", lambda e: command())
# 備份按鈕動作
def backup_action():
backup_dir = entry_path.get()
if backup_dir:
run_task_in_thread(backup_drivers, backup_dir)
else:
messagebox.showwarning("警告", "請選擇備份目錄")
# 還原按鈕動作
def restore_action():
backup_dir = entry_path.get()
if backup_dir:
run_task_in_thread(restore_drivers, backup_dir)
else:
messagebox.showwarning("警告", "請選擇還原目錄")
# 建立主視窗
root = tk.Tk()
root.title("驅動程式備份與還原")
root.geometry("900x350") # 設定窗口大小
root.configure(bg="deepskyblue") # 設定背景顏色
# 設定字體大小
font_style = ("Arial", 14)
# 路徑選擇框
label_path = tk.Label(root, text="選擇備份/還原目錄:", bg="deepskyblue", font=font_style)
label_path.grid(row=0, column=0, padx=10, pady=10)
entry_path = tk.Entry(root, width=50, font=font_style)
entry_path.grid(row=0, column=1, padx=10, pady=10)
button_browse = tk.Button(root, text="瀏覽", command=select_directory, font=font_style)
button_browse.grid(row=0, column=2, padx=10, pady=10)
# 進度條
progress_bar = ttk.Progressbar(root, mode='indeterminate', length=300)
progress_bar.grid(row=1, column=0, columnspan=3, padx=10, pady=10)
# 建立 Canvas 用來畫圓角按鈕
canvas = tk.Canvas(root, width=900, height=150, bg="deepskyblue", highlightthickness=0)
canvas.grid(row=2, column=0, columnspan=3)
# 創建圓角按鈕
create_rounded_button(canvas, "備份驅動程式", backup_action, 200, 50, 200, 50, "gold")
create_rounded_button(canvas, "還原驅動程式", restore_action, 500, 50, 200, 50, "tomato")
# 底部資訊欄
label_footer = tk.Label(root, text="設計者: WCS;時間: 2024年9月;版本: 1.0.2;備註: 測試版本",
bg="deepskyblue", font=("Arial", 12), justify="left")
label_footer.grid(row=3, column=0, columnspan=3, padx=10, pady=20, sticky="s")
# 主視窗執行
root.mainloop()
backupdrivers02_pnp
import os
import subprocess
import threading
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
# 列出驅動程式並進行分類
def list_drivers():
try:
command = "pnputil /enum-drivers"
result = subprocess.run(command, shell=True, capture_output=True, text=True, check=True)
drivers = parse_driver_list(result.stdout)
categorized_drivers = categorize_drivers(drivers)
return categorized_drivers
except subprocess.CalledProcessError as e:
messagebox.showerror("錯誤", f"無法列出驅動程式,錯誤信息:{e}")
return {}
# 解析驅動程式列表
def parse_driver_list(output):
lines = output.splitlines()
drivers = []
current_driver = {}
for line in lines:
if "Published Name" in line:
current_driver = {"name": line.split(":")[1].strip()}
if "Driver Package Provider" in line:
current_driver["provider"] = line.split(":")[1].strip()
if "Class Name" in line:
current_driver["class"] = line.split(":")[1].strip()
drivers.append(current_driver)
current_driver = {}
return drivers
# 將驅動程式分類
def categorize_drivers(drivers):
categories = {"系統": [], "印表機": [], "網路卡": [], "其他": []}
for driver in drivers:
driver_class = driver.get("class", "其他")
if "system" in driver_class.lower():
categories["系統"].append(driver)
elif "printer" in driver_class.lower():
categories["印表機"].append(driver)
elif "network" in driver_class.lower():
categories["網路卡"].append(driver)
else:
categories["其他"].append(driver)
return categories
# 備份選定的驅動程式
def backup_selected_drivers(backup_dir, selected_items):
if not os.path.exists(backup_dir):
os.makedirs(backup_dir)
try:
for item in selected_items:
driver_info = driver_list.item(item, "values")
driver_name = driver_info[0] # 取出名稱
command = f"pnputil /export-driver {driver_name} {backup_dir}"
subprocess.run(command, shell=True, check=True)
messagebox.showinfo("成功", f"選定的驅動程式已成功備份至 {backup_dir}")
except subprocess.CalledProcessError as e:
messagebox.showerror("錯誤", f"備份失敗,錯誤信息:{e}")
# 啟動進度條並執行程序
def run_task_in_thread(task, *args):
progress_bar.start() # 開始進度條滾動
task_thread = threading.Thread(target=lambda: run_task(task, *args))
task_thread.start()
# 執行具體的備份或還原任務
def run_task(task, *args):
try:
task(*args) # 執行具體的任務
finally:
progress_bar.stop() # 結束進度條滾動
# 選擇目錄
def select_directory():
path = filedialog.askdirectory()
if path:
entry_path.delete(0, tk.END)
entry_path.insert(0, path)
# 查詢驅動程式並顯示在列表中
def search_drivers():
driver_list.delete(*driver_list.get_children()) # 清空列表
drivers = list_drivers()
for category, driver_group in drivers.items():
driver_list.insert("", "end", values=(category, "", ""))
for driver in driver_group:
driver_list.insert("", "end", values=(driver["name"], driver["provider"], driver["class"]))
# 備份按鈕動作
def backup_action():
backup_dir = entry_path.get()
if backup_dir:
selected_items = driver_list.selection()
if selected_items:
run_task_in_thread(backup_selected_drivers, backup_dir, selected_items)
else:
messagebox.showwarning("警告", "請選擇至少一個驅動程式進行備份")
else:
messagebox.showwarning("警告", "請選擇備份目錄")
# 還原按鈕動作
def restore_action():
backup_dir = entry_path.get()
if backup_dir:
run_task_in_thread(restore_drivers, backup_dir)
else:
messagebox.showwarning("警告", "請選擇還原目錄")
# 建立主視窗
root = tk.Tk()
root.title("驅動程式備份與還原")
root.geometry("1000x600") # 設定窗口大小
root.configure(bg="deepskyblue") # 設定背景顏色
# 設定字體大小
font_style = ("Arial", 14)
# 路徑選擇框
label_path = tk.Label(root, text="選擇備份/還原目錄:", bg="deepskyblue", font=font_style)
label_path.grid(row=0, column=0, padx=10, pady=10)
entry_path = tk.Entry(root, width=50, font=font_style)
entry_path.grid(row=0, column=1, padx=10, pady=10)
button_browse = tk.Button(root, text="瀏覽", command=select_directory, font=font_style)
button_browse.grid(row=0, column=2, padx=10, pady=10)
# 進度條
progress_bar = ttk.Progressbar(root, mode='indeterminate', length=300)
progress_bar.grid(row=1, column=0, columnspan=3, padx=10, pady=10)
# 驅動程式選擇區域
label_drivers = tk.Label(root, text="選擇要備份的驅動程式:", bg="deepskyblue", font=font_style)
label_drivers.grid(row=2, column=0, columnspan=3, padx=10, pady=10)
# 驅動程式列表區域,使用 Treeview
driver_list = ttk.Treeview(root, columns=("name", "provider", "class"), show="headings", height=10)
driver_list.grid(row=3, column=0, columnspan=3, padx=10, pady=10)
# 設定欄位名稱
driver_list.heading("name", text="名稱")
driver_list.heading("provider", text="提供者")
driver_list.heading("class", text="分類")
# 查詢驅動程式按鈕
button_search = tk.Button(root, text="查詢驅動程式", command=search_drivers, font=font_style, bg="lightblue")
button_search.grid(row=4, column=0, padx=10, pady=10)
# 備份和還原按鈕
button_backup = tk.Button(root, text="備份選定驅動程式", command=backup_action, font=font_style, bg="gold")
button_backup.grid(row=4, column=1, padx=10, pady=10)
button_restore = tk.Button(root, text="還原驅動程式", command=restore_action, font=font_style, bg="tomato")
button_restore.grid(row=4, column=2, padx=10, pady=10)
# 底部資訊欄
label_footer = tk.Label(root, text="設計者: 您的名稱\n時間: 2024年9月\n版本: 1.0.0\n備註: 測試版本",
bg="deepskyblue", font=("Arial", 12), justify="left")
label_footer.grid(row=5, column=0, columnspan=3, padx=10, pady=20, sticky="s")
# 主視窗執行
root.mainloop()