import tkinter as tk
from tkinter import filedialog, messagebox
import subprocess
import os
# ===============================================
# Script: VHDX_Diff_Merge_Tool.py
# Description: A GUI tool for managing VHDX files, including creating differencing disks, mounting, dismounting, and merging VHDX files.
# Version: 1.3
# Author: [Wang CS]
# Date: [2024-09-09]
# ===============================================
# Create the main window
window = tk.Tk()
window.title("VHDX 差異與合併工具")
window.geometry("600x450")
# Function: Select the base VHDX file
def select_base_vhdx_file():
file_path = filedialog.askopenfilename(
title="選擇基礎 VHDX 文件",
filetypes=[("VHDX 檔案", "*.vhdx")]
)
base_vhdx_entry.delete(0, tk.END)
base_vhdx_entry.insert(0, file_path)
# Function: Select the differencing VHDX file save path
def select_diff_vhdx_file():
file_path = filedialog.asksaveasfilename(
title="選擇保存差分 VHDX 文件",
defaultextension=".vhdx",
filetypes=[("VHDX 檔案", "*.vhdx")]
)
diff_vhdx_entry.delete(0, tk.END)
diff_vhdx_entry.insert(0, file_path)
# Function: Select the VHDX file for mounting, dismounting, or merging
def select_operation_vhdx_file():
file_path = filedialog.askopenfilename(
title="選擇 VHDX 文件",
filetypes=[("VHDX 檔案", "*.vhdx")]
)
operation_vhdx_entry.delete(0, tk.END)
operation_vhdx_entry.insert(0, file_path)
# Function: Create a differencing VHDX disk
def create_diff_vhdx():
base_vhdx = base_vhdx_entry.get()
diff_vhdx = diff_vhdx_entry.get()
if not base_vhdx or not diff_vhdx:
messagebox.showerror("錯誤", "請選擇基礎 VHDX 文件和差分 VHDX 文件的保存路徑。")
return
if not os.path.exists(base_vhdx):
messagebox.showerror("錯誤", "基礎 VHDX 文件不存在。")
return
command = f'New-VHD -Path "{diff_vhdx}" -ParentPath "{base_vhdx}" -Differencing'
try:
subprocess.run(["powershell", "-Command", command], check=True)
messagebox.showinfo("成功", "差分 VHDX 文件創建成功!")
except subprocess.CalledProcessError as e:
messagebox.showerror("錯誤", f"無法創建差分 VHDX 文件。\n{e}")
# Function: Mount the VHDX file
def mount_vhdx():
vhdx_file = operation_vhdx_entry.get()
if vhdx_file:
command = f'Mount-VHD -Path "{vhdx_file}"'
try:
subprocess.run(["powershell", "-Command", command], check=True)
messagebox.showinfo("成功", "VHDX 加載成功!")
except subprocess.CalledProcessError as e:
messagebox.showerror("錯誤", f"無法加載 VHDX 文件。\n{e}")
else:
messagebox.showerror("錯誤", "請選擇要掛載的 VHDX 文件。")
# Function: Dismount the VHDX file
def dismount_vhdx():
vhdx_file = operation_vhdx_entry.get()
if vhdx_file:
command = f'Dismount-VHD -Path "{vhdx_file}"'
try:
subprocess.run(["powershell", "-Command", command], check=True)
messagebox.showinfo("成功", "VHDX 卸載成功!")
except subprocess.CalledProcessError as e:
messagebox.showerror("錯誤", f"無法卸載 VHDX 文件。\n{e}")
else:
messagebox.showerror("錯誤", "請選擇要卸載的 VHDX 文件。")
# Function: Merge the VHDX file
def merge_vhdx():
vhdx_file = operation_vhdx_entry.get()
if vhdx_file:
command = f'Merge-VHD -Path "{vhdx_file}" -Mode Full'
try:
subprocess.run(["powershell", "-Command", command], check=True)
messagebox.showinfo("成功", "VHDX 文件合併成功!")
except subprocess.CalledProcessError as e:
messagebox.showerror("錯誤", f"無法合併 VHDX 文件。\n{e}")
else:
messagebox.showerror("錯誤", "請選擇要合併的 VHDX 文件。")
# GUI Components
# Version and Author Information at the top
info_frame = tk.Frame(window)
info_frame.pack(pady=10)
version_label = tk.Label(info_frame, text="版本: 1.2", font=("Arial", 10, "bold"))
version_label.grid(row=0, column=0, padx=10)
author_label = tk.Label(info_frame, text="作者: [WANG-CS]", font=("Arial", 10))
author_label.grid(row=0, column=1, padx=10)
date_label = tk.Label(info_frame, text="日期: [2024-09-09]", font=("Arial", 10))
date_label.grid(row=0, column=2, padx=10)
# Section for creating a differencing disk
diff_frame = tk.LabelFrame(window, text="創建差分 VHDX", padx=10, pady=10)
diff_frame.pack(padx=10, pady=10, fill="both", expand="yes")
base_vhdx_label = tk.Label(diff_frame, text="基礎 VHDX 路徑:")
base_vhdx_label.grid(row=0, column=0, sticky="e", pady=5)
base_vhdx_entry = tk.Entry(diff_frame, width=40)
base_vhdx_entry.grid(row=0, column=1, pady=5, padx=5)
browse_base_button = tk.Button(diff_frame, text="瀏覽", command=select_base_vhdx_file)
browse_base_button.grid(row=0, column=2, pady=5, padx=5)
diff_vhdx_label = tk.Label(diff_frame, text="差分 VHDX 保存路徑:")
diff_vhdx_label.grid(row=1, column=0, sticky="e", pady=5)
diff_vhdx_entry = tk.Entry(diff_frame, width=40)
diff_vhdx_entry.grid(row=1, column=1, pady=5, padx=5)
browse_diff_button = tk.Button(diff_frame, text="瀏覽", command=select_diff_vhdx_file)
browse_diff_button.grid(row=1, column=2, pady=5, padx=5)
create_diff_button = tk.Button(diff_frame, text="創建差分磁碟", command=create_diff_vhdx)
create_diff_button.grid(row=2, column=1, pady=10)
# Section for VHDX file operations
operation_frame = tk.LabelFrame(window, text="操作 VHDX 文件", padx=10, pady=10)
operation_frame.pack(padx=10, pady=10, fill="both", expand="yes")
operation_vhdx_label = tk.Label(operation_frame, text="選擇 VHDX 文件:")
operation_vhdx_label.grid(row=0, column=0, sticky="e", pady=5)
operation_vhdx_entry = tk.Entry(operation_frame, width=40)
operation_vhdx_entry.grid(row=0, column=1, pady=5, padx=5)
browse_operation_button = tk.Button(operation_frame, text="瀏覽", command=select_operation_vhdx_file)
browse_operation_button.grid(row=0, column=2, pady=5, padx=5)
mount_button = tk.Button(operation_frame, text="掛載 VHDX", width=15, command=mount_vhdx)
mount_button.grid(row=1, column=0, pady=10, padx=5)
dismount_button = tk.Button(operation_frame, text="卸載 VHDX", width=15, command=dismount_vhdx)
dismount_button.grid(row=1, column=1, pady=10, padx=5)
merge_button = tk.Button(operation_frame, text="合併 VHDX", width=15, command=merge_vhdx)
merge_button.grid(row=1, column=2, pady=10, padx=5)
# Run the main loop
window.mainloop()