Advertisement
Najeebsk

VHD-EXPLORER.pyw

Sep 25th, 2024 (edited)
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.10 KB | None | 0 0
  1. import os
  2. import subprocess
  3. import tkinter as tk
  4. from tkinter import filedialog, messagebox, Listbox, Scrollbar, Entry
  5. import ctypes
  6. import sys
  7. import string
  8.  
  9. def is_admin():
  10.     """ Check if the script is running with admin privileges """
  11.     try:
  12.         return ctypes.windll.shell32.IsUserAnAdmin()
  13.     except:
  14.         return False
  15.  
  16. def browse_vhd():
  17.     """ Browse for a VHD file and display its path in the entry field """
  18.     vhd_file = filedialog.askopenfilename(filetypes=[("VHD files", "*.vhd")])
  19.     if vhd_file:
  20.         vhd_entry.delete(0, tk.END)  # Clear existing entry
  21.         vhd_entry.insert(0, vhd_file)  # Insert selected file path
  22.  
  23. def get_drive_letters():
  24.     """ Get a list of current drive letters """
  25.     return [d for d in string.ascii_uppercase if os.path.exists(f"{d}:\\")]
  26.  
  27. def mount_vhd():
  28.     """ Mount the selected VHD file using DiskPart and auto-detect the new drive """
  29.     vhd_file = vhd_entry.get()
  30.  
  31.     # Ensure a VHD file is selected
  32.     if not vhd_file.endswith('.vhd'):
  33.         messagebox.showerror("Invalid File", "Please select a valid .vhd file.")
  34.         return
  35.  
  36.     # Ensure the file exists
  37.     if not os.path.exists(vhd_file):
  38.         messagebox.showerror("File Not Found", "The selected VHD file does not exist.")
  39.         return
  40.  
  41.     # Correct the path format (convert / to \)
  42.     vhd_file = vhd_file.replace("/", "\\")
  43.  
  44.     # Get current drive letters before mounting
  45.     drives_before = get_drive_letters()
  46.  
  47.     try:
  48.         # Create a DiskPart script to mount the VHD
  49.         diskpart_script = f"""
  50.        select vdisk file="{vhd_file}"
  51.        attach vdisk
  52.        """
  53.         script_path = 'mount_vhd.txt'
  54.  
  55.         # Write the DiskPart script to a file
  56.         with open(script_path, 'w') as f:
  57.             f.write(diskpart_script.strip())
  58.  
  59.         # Execute the DiskPart command with the script
  60.         result = subprocess.run(['diskpart', '/s', script_path], capture_output=True, text=True)
  61.  
  62.         # Check if DiskPart ran successfully
  63.         if result.returncode == 0:
  64.             messagebox.showinfo("Success", f"VHD file {vhd_file} mounted successfully.")
  65.  
  66.             # Get the new drive letters after mounting
  67.             drives_after = get_drive_letters()
  68.             new_drive = list(set(drives_after) - set(drives_before))  # Find the new drive letter
  69.  
  70.             if new_drive:
  71.                 mounted_drive = new_drive[0] + ":\\"
  72.                 print(f"VHD mounted at {mounted_drive}")
  73.                 show_files_in_vhd(mounted_drive)  # Show files in the new drive
  74.             else:
  75.                 messagebox.showerror("Error", "No new drive detected. Mounting might have failed.")
  76.         else:
  77.             # Capture and show detailed DiskPart error output
  78.             error_message = f"DiskPart failed with error:\n{result.stderr}"
  79.             print(error_message)  # Print error to console
  80.             messagebox.showerror("DiskPart Error", error_message)
  81.  
  82.     except Exception as e:
  83.         messagebox.showerror("Error", f"An error occurred: {e}")
  84.     finally:
  85.         # Clean up the DiskPart script file
  86.         if os.path.exists(script_path):
  87.             os.remove(script_path)
  88.  
  89. def unmount_vhd():
  90.     """ Unmount the selected VHD file using DiskPart """
  91.     vhd_file = vhd_entry.get()
  92.  
  93.     # Ensure a VHD file is selected
  94.     if not vhd_file.endswith('.vhd'):
  95.         messagebox.showerror("Invalid File", "Please select a valid .vhd file.")
  96.         return
  97.  
  98.     # Ensure the file exists
  99.     if not os.path.exists(vhd_file):
  100.         messagebox.showerror("File Not Found", "The selected VHD file does not exist.")
  101.         return
  102.  
  103.     # Correct the path format (convert / to \)
  104.     vhd_file = vhd_file.replace("/", "\\")
  105.  
  106.     try:
  107.         # Create a DiskPart script to unmount the VHD
  108.         diskpart_script = f"""
  109.        select vdisk file="{vhd_file}"
  110.        detach vdisk
  111.        """
  112.         script_path = 'unmount_vhd.txt'
  113.  
  114.         # Write the DiskPart script to a file
  115.         with open(script_path, 'w') as f:
  116.             f.write(diskpart_script.strip())
  117.  
  118.         # Execute the DiskPart command with the script
  119.         result = subprocess.run(['diskpart', '/s', script_path], capture_output=True, text=True)
  120.  
  121.         # Check if DiskPart ran successfully
  122.         if result.returncode == 0:
  123.             messagebox.showinfo("Success", f"VHD file {vhd_file} unmounted successfully.")
  124.             # Clear file list after unmounting
  125.             file_list.delete(0, tk.END)
  126.         else:
  127.             # Capture and show detailed DiskPart error output
  128.             error_message = f"DiskPart failed with error:\n{result.stderr}"
  129.             print(error_message)  # Print error to console
  130.             messagebox.showerror("DiskPart Error", error_message)
  131.  
  132.     except Exception as e:
  133.         messagebox.showerror("Error", f"An error occurred: {e}")
  134.     finally:
  135.         # Clean up the DiskPart script file
  136.         if os.path.exists(script_path):
  137.             os.remove(script_path)
  138.  
  139. def show_files_in_vhd(mounted_drive):
  140.     """ Show all files and folders inside the mounted VHD """
  141.     if not os.path.exists(mounted_drive):
  142.         messagebox.showerror("Error", "The mounted drive does not exist.")
  143.         return
  144.  
  145.     # Clear the file list before adding new items
  146.     file_list.delete(0, tk.END)
  147.  
  148.     global all_files  # Use the global all_files variable
  149.     all_files = []  # Reset the all_files list
  150.  
  151.     for root, dirs, files in os.walk(mounted_drive):
  152.         for name in dirs:
  153.             full_path = os.path.join(root, name)
  154.             file_list.insert(tk.END, full_path)
  155.             all_files.append(full_path)  # Add directory to all_files
  156.         for name in files:
  157.             full_path = os.path.join(root, name)
  158.             file_list.insert(tk.END, full_path)
  159.             all_files.append(full_path)  # Add file to all_files
  160.  
  161. def open_file(event):
  162.     """ Open the selected file with the default program """
  163.     selected_file = file_list.get(file_list.curselection())
  164.     os.startfile(selected_file)  # Open with default program
  165.  
  166. def search_files():
  167.     """ Search for files in the mounted VHD """
  168.     search_query = search_entry.get().lower()
  169.  
  170.     if not all_files:  # Check if all_files is populated
  171.         messagebox.showerror("Error", "No files to search. Make sure the VHD is mounted.")
  172.         return
  173.  
  174.     file_list.delete(0, tk.END)  # Clear the file list
  175.     for item in all_files:  # Use the global all_files variable
  176.         if search_query in os.path.basename(item).lower():
  177.             file_list.insert(tk.END, item)
  178.  
  179. def main():
  180.     """ Main function to run the application """
  181.     if is_admin():
  182.         global all_files  # Store all files in a global variable
  183.         all_files = []  # Initialize all_files
  184.  
  185.         # Tkinter GUI setup
  186.         root = tk.Tk()
  187.         root.title("Najeeb VHD Mounter")
  188.  
  189.         # Set the window size to 900x600
  190.         root.geometry("1000x700")
  191.  
  192.         # VHD selection
  193.         vhd_label = tk.Label(root, text="Select VHD File:", font=("Arial", 14), bg="lightblue")
  194.         vhd_label.grid(row=0, column=0, padx=10, pady=10, sticky='w')
  195.  
  196.         global vhd_entry
  197.         vhd_entry = tk.Entry(root, width=60, font=("Arial", 14))
  198.         vhd_entry.grid(row=0, column=1, padx=10, pady=10)
  199.  
  200.         browse_button = tk.Button(root, text="Browse", command=browse_vhd, font=("Arial", 12), bg="lightgreen")
  201.         browse_button.grid(row=0, column=2, padx=10, pady=10)
  202.  
  203.         # Mount button
  204.         mount_button = tk.Button(root, text="Mount VHD", command=mount_vhd, font=("Arial", 12), bg="lightgreen")
  205.         mount_button.grid(row=1, column=0, padx=10, pady=10)
  206.  
  207.         # Unmount button
  208.         unmount_button = tk.Button(root, text="Unmount VHD", command=unmount_vhd, font=("Arial", 12), bg="lightgreen")
  209.         unmount_button.grid(row=1, column=2, padx=10, pady=10)
  210.  
  211.         # File Listbox with scrollbar
  212.         global file_list
  213.         file_list = Listbox(root, width=106, height=25, font=("Arial", 12))
  214.         file_list.grid(row=2, column=0, columnspan=3, padx=10, pady=10)
  215.  
  216.         scrollbar = Scrollbar(root)
  217.         scrollbar.grid(row=2, column=3, sticky='ns')
  218.         file_list.config(yscrollcommand=scrollbar.set)
  219.         scrollbar.config(command=file_list.yview)
  220.  
  221.         # Bind double-click to open file
  222.         file_list.bind('<Double-Button-1>', open_file)
  223.  
  224.         # Search functionality
  225.         search_label = tk.Label(root, text="Search:", font=("Arial", 14), bg="lightblue")
  226.         search_label.grid(row=3, column=0, padx=10, pady=10, sticky='w')
  227.  
  228.         global search_entry
  229.         search_entry = Entry(root, width=60, font=("Arial", 14))
  230.         search_entry.grid(row=3, column=1, padx=10, pady=10)
  231.  
  232.         search_button = tk.Button(root, text="Search", command=search_files, font=("Arial", 12), bg="lightgreen")
  233.         search_button.grid(row=3, column=2, padx=10, pady=10)
  234.  
  235.         root.mainloop()
  236.     else:
  237.         # Rerun the script with admin privileges if not running as admin
  238.         ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
  239.  
  240. if __name__ == "__main__":
  241.     main()
  242.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement