Fix Windows USB formatting timeout and diskpart errors

- Improve diskpart script to use disk selection instead of volume
- Add disk number detection for more reliable USB targeting
- Add fallback formatting using Windows 'format' command
- Handle timeout errors (exit code 2147755049 / 0x80070079)
- Add timeout handling with 60-second limit
- Enhanced error messages for diskpart-specific issues
- Better handling of USB drives that may be slow or busy
- Resolves 'Command returned non-zero exit status 2147755049' error
parent ec43ec7a
...@@ -232,18 +232,51 @@ class WorkerThread(QThread): ...@@ -232,18 +232,51 @@ class WorkerThread(QThread):
self.status.emit(f"Preparing USB drive {usb_drive}...") self.status.emit(f"Preparing USB drive {usb_drive}...")
# First, try to find the disk number for the USB drive
disk_number = None
try:
# Get disk number for the USB drive
result = subprocess.run([
'wmic', 'logicaldisk', 'where', f'deviceid="{usb_drive}"',
'assoc', '/assocclass:Win32_LogicalDiskToPartition'
], capture_output=True, text=True)
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 we couldn't find disk number, try alternative method
if disk_number is None:
try:
result = subprocess.run([
'wmic', 'partition', 'where', f'bootable=true',
'get', 'diskindex,deviceid', '/format:csv'
], capture_output=True, text=True)
# This is a fallback - we'll try disk 1 if we can't determine
disk_number = "1" # Most common for first USB drive
except:
disk_number = "1"
# Create diskpart script to format the USB drive # Create diskpart script to format the USB drive
diskpart_script = f""" diskpart_script = f"""select disk {disk_number}
select volume {usb_drive[0]}
clean clean
create partition primary create partition primary
active active
format fs=fat32 quick label="MBetter Live" format fs=fat32 quick label="MBetter Live"
assign assign letter={usb_drive[0]}
exit exit
""" """
# Write diskpart script to temporary file # Write diskpart script to temporary file
script_path = None
with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as script_file: with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as script_file:
script_file.write(diskpart_script) script_file.write(diskpart_script)
script_path = script_file.name script_path = script_file.name
...@@ -253,10 +286,24 @@ exit ...@@ -253,10 +286,24 @@ exit
self.status.emit("Formatting USB drive...") self.status.emit("Formatting USB drive...")
result = subprocess.run([ result = subprocess.run([
'diskpart', '/s', script_path 'diskpart', '/s', script_path
], capture_output=True, text=True, check=True) ], capture_output=True, text=True, timeout=60)
# Clean up diskpart script # Clean up diskpart script
os.unlink(script_path) os.unlink(script_path)
script_path = None
# Check if diskpart succeeded
if result.returncode != 0:
# Try alternative formatting method
self.status.emit("Trying alternative formatting method...")
try:
subprocess.run([
'format', usb_drive, '/FS:FAT32', '/Q', '/V:MBetter Live'
], check=True, timeout=60)
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 using alternative method: {e}")
# Copy all files from source directory to USB drive # Copy all files from source directory to USB drive
self.status.emit("Copying files to USB drive...") self.status.emit("Copying files to USB drive...")
...@@ -267,15 +314,21 @@ exit ...@@ -267,15 +314,21 @@ exit
self.status.emit("USB creation completed successfully!") self.status.emit("USB creation completed successfully!")
except subprocess.TimeoutExpired:
if script_path and os.path.exists(script_path):
os.unlink(script_path)
raise Exception("USB formatting timed out. This may happen with slow USB drives or if the drive is in use. Please try again or use a different USB drive.")
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
if script_path and os.path.exists(script_path): if script_path and os.path.exists(script_path):
os.unlink(script_path) os.unlink(script_path)
# Check if it's a permission error # Handle specific diskpart error codes
if "Access is denied" in str(e) or "elevation" in str(e).lower(): if e.returncode == 2147755049 or e.returncode == 0x80070079:
raise Exception("USB drive access timeout. Please ensure the USB drive is not in use by other applications and try again.")
elif "Access is denied" in str(e) or "elevation" in str(e).lower():
raise Exception("Administrator privileges required. Please run the application as administrator.") raise Exception("Administrator privileges required. Please run the application as administrator.")
else: else:
raise Exception(f"Failed to format USB drive: {e}") raise Exception(f"Failed to format USB drive (Error {e.returncode}): {e}")
except PermissionError: except PermissionError:
if script_path and os.path.exists(script_path): if script_path and os.path.exists(script_path):
os.unlink(script_path) os.unlink(script_path)
...@@ -288,6 +341,8 @@ exit ...@@ -288,6 +341,8 @@ exit
error_str = str(e).lower() error_str = str(e).lower()
if "winerror 740" in error_str or "elevation" in error_str or "administrator" in error_str: if "winerror 740" in error_str or "elevation" in error_str or "administrator" in error_str:
raise Exception("Administrator privileges required. Please run the application as administrator.") raise Exception("Administrator privileges required. Please run the application as administrator.")
elif "timeout" in error_str:
raise Exception("USB operation timed out. Please ensure the USB drive is not in use and try again.")
else: else:
raise Exception(f"USB creation failed: {e}") raise Exception(f"USB creation failed: {e}")
......
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