Replace diskpart with PowerShell for more reliable Windows USB formatting

- Use PowerShell Format-Volume cmdlet as primary formatting method
- More reliable than diskpart with better error handling
- Get drive information before formatting for verification
- Keep diskpart as fallback method only
- PowerShell doesn't require script files and works more consistently
- Should resolve blank diskpart window and script access issues
- Modern approach using native Windows PowerShell cmdlets
parent 30760e9e
......@@ -221,7 +221,7 @@ class WorkerThread(QThread):
os.unlink(temp_iso)
def write_usb_windows(self, source_dir):
# Windows USB writing implementation
# Windows USB writing implementation using PowerShell (more reliable than diskpart)
import tempfile
import subprocess
......@@ -232,41 +232,106 @@ class WorkerThread(QThread):
self.status.emit(f"Preparing USB drive {usb_drive}...")
# First, try to find the disk number for the USB drive
disk_number = None
# Use PowerShell to format the USB drive (more reliable than diskpart)
try:
# Get disk number for the USB drive
# First, get drive information
self.status.emit("Getting drive information...")
drive_info_cmd = f'Get-Volume -DriveLetter {usb_drive[0]} | Select-Object DriveLetter,FileSystemLabel,Size'
result = subprocess.run([
'wmic', 'logicaldisk', 'where', f'deviceid="{usb_drive}"',
'assoc', '/assocclass:Win32_LogicalDiskToPartition'
], capture_output=True, text=True)
'powershell', '-Command', drive_info_cmd
], capture_output=True, text=True, timeout=30)
for line in result.stdout.split('\n'):
if 'Disk #' in line:
# Extract disk number
import re
match = re.search(r'Disk #(\d+)', line)
if match:
disk_number = match.group(1)
break
except:
pass
if result.returncode == 0:
self.status.emit(f"Drive info: {result.stdout.strip()}")
# Format the USB drive using PowerShell
self.status.emit("Formatting USB drive with PowerShell...")
format_cmd = f'Format-Volume -DriveLetter {usb_drive[0]} -FileSystem FAT32 -NewFileSystemLabel "MBetter Live" -Force -Confirm:$false'
result = subprocess.run([
'powershell', '-Command', format_cmd
], capture_output=True, text=True, timeout=120)
self.status.emit(f"PowerShell format exit code: {result.returncode}")
if result.stdout:
self.status.emit(f"PowerShell stdout: {result.stdout}")
if result.stderr:
self.status.emit(f"PowerShell stderr: {result.stderr}")
if result.returncode != 0:
raise Exception(f"PowerShell format failed (exit code {result.returncode}): {result.stderr}")
except subprocess.TimeoutExpired:
raise Exception("USB formatting timed out. Please try with a different USB drive.")
except subprocess.CalledProcessError as e:
raise Exception(f"Failed to format USB drive with PowerShell: {e}")
except Exception as e:
# Fallback to old diskpart method if PowerShell fails
self.status.emit("PowerShell formatting failed, trying diskpart as fallback...")
return self._write_usb_windows_diskpart_fallback(source_dir)
# Copy all files from source directory to USB drive after successful formatting
self.status.emit("Copying files to USB drive...")
self._copy_directory_windows(source_dir, f"{usb_drive}\\")
# Make it bootable by ensuring boot files are in the right place
self._make_bootable_windows(source_dir, usb_drive)
self.status.emit("USB creation completed successfully!")
def _write_usb_windows_diskpart_fallback(self, source_dir):
"""Fallback diskpart method for when PowerShell fails"""
# Get USB drive letter
usb_drive = self.usb_device
if not usb_drive.endswith(':'):
usb_drive += ':'
# Find disk number for the USB drive
disk_number = "1" # Default fallback
# Create diskpart script
diskpart_script = f"""select disk {disk_number}
# Write diskpart script to accessible location
script_filename = f'diskpart_script_{os.getpid()}.txt'
script_path = os.path.join(os.path.expanduser('~'), script_filename)
# If we couldn't find disk number, try alternative method
if disk_number is None:
try:
with open(script_path, 'w', encoding='cp1252') as script_file:
script_file.write(diskpart_script)
self.status.emit(f"Diskpart fallback: Created script at {script_path}")
# Run diskpart
result = subprocess.run([
'wmic', 'partition', 'where', f'bootable=true',
'get', 'diskindex,deviceid', '/format:csv'
], capture_output=True, text=True)
'diskpart', '/s', script_path
], capture_output=True, text=True, timeout=60)
# This is a fallback - we'll try disk 1 if we can't determine
disk_number = "1" # Most common for first USB drive
# Clean up script
try:
os.unlink(script_path)
except:
disk_number = "1"
pass
# Create diskpart script to format the USB drive
diskpart_script = f"""select disk {disk_number}
if result.returncode != 0:
raise Exception(f"Diskpart fallback failed (exit code {result.returncode}): {result.stderr}")
# Copy files after successful formatting
self.status.emit("Copying files to USB drive...")
self._copy_directory_windows(source_dir, f"{usb_drive}\\")
# Make it bootable
self._make_bootable_windows(source_dir, usb_drive)
self.status.emit("USB creation completed successfully with diskpart fallback!")
except Exception as e:
if os.path.exists(script_path):
try:
os.unlink(script_path)
except:
pass
raise Exception(f"Diskpart fallback failed: {e}")
clean
create partition primary
active
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment