bobomb Posted December 5, 2021 Author Posted December 5, 2021 (edited) @benners and this is the final working script using your method, you were 100% correct that drive letters were being skipped and needed to be moved. THANK you.. I even removed some global variables and made them local expandcollapse popup#NoTrayIcon #RequireAdmin #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=PrepareDiskNT.ico #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Res_Comment=Place in a subfolder to WinNTSetup5 (e.g. C:\WinNTSetup5\Prep) #AutoIt3Wrapper_Res_Description=PrepareDiskNT for WinNTSetup5 #AutoIt3Wrapper_Res_Fileversion=1.3 #AutoIt3Wrapper_Add_Constants=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <ListBoxConstants.au3> #include <Constants.au3> #include <File.au3> #include <Array.au3> #include <String.au3> Global $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive _Cleanup() DirCreate(@WorkingDir & '\cache') $listFile = FileOpen(@WorkingDir & '\cache\list.ini', 2) FileWrite($listFile, 'lis dis') FileClose($listFile) GUICreate('Prep/Format Disk v1.3', 300, 298) GUISetIcon (@WorkingDir & '\PrepareDiskNT.ico',1) GUISetBkColor (0x797979) GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280) $DiskList = GUICtrlCreateList('', 20, 30, 260, 150) GUICtrlSetData(-1, _GetInfo()) $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25) GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30) $MBR = GUICtrlCreateButton('BIOS (MBR) Boot',20, 232, 120, 40) $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40) GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30) GUISetState() Do $Selection = GUIGetMsg() If $Selection = $MBR Then Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $iMsgBoxAnswer If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $iMsgBoxAnswer = 6 ;Yes _FormatMBR($DiskN[6]) _IniWriteMBR() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive) Run("cmd /c ..\WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE) _Cleanup() Exit Case $iMsgBoxAnswer = 7 ;No EndSelect EndIf EndIf If $Selection = $GPT Then Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $iMsgBoxAnswer If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $iMsgBoxAnswer = 6 ;Yes _FormatGPT($DiskN[6]) _IniWriteGPT() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive) Run("cmd /c ..\WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE) _Cleanup() Exit Case $iMsgBoxAnswer = 7 ;No EndSelect EndIf EndIf If $Selection = $Refresh Then GUICtrlSetData($DiskList, "") GUICtrlSetData($DiskList, _GetInfo()) EndIf Until $Selection = $GUI_EVENT_CLOSE _Cleanup() Func _GetInfo() RunWait("cmd /c diskpart /s cache\list.ini>cache\list.txt", @WorkingDir, @SW_HIDE) ; Only works when compiled if x64 Local $Filtered = '', $RawList, $Array = _StringExplode(FileRead(@WorkingDir & '\cache\list.txt'), @LF) For $RawList = 0 To UBound($Array) - 1 If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|' Next $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '') ;Removal of spaces, returns, line breaks, and pipes from end of the string Return $Filtered EndFunc ;==>_GetInfo Func _FormatMBR($Drive) _GetDriveLetters() GUISetState(@SW_HIDE) $cleandatFile = FileOpen(@WorkingDir & '\cache\clean.dat', 2) FileWrite($cleandatFile, 'Sel Dis ' & $Drive) FileWrite($cleandatFile, @CRLF & 'clean') FileClose($cleandatFile) $attribdatFile = FileOpen(@WorkingDir & '\cache\attrib.dat', 2) FileWrite($attribdatFile, 'Sel Dis ' & $Drive) FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly') FileClose($attribdatFile) $scrubdatFile = FileOpen(@WorkingDir & '\cache\scrub.dat', 2) FileWrite($scrubdatFile, 'Sel Dis ' & $Drive) FileWrite($scrubdatFile, @CRLF & 'cre par pri') FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=MBRscrubber') FileClose($scrubdatFile) $convertFile = FileOpen(@WorkingDir & '\cache\convert.dat', 2) FileWrite($convertFile, 'Sel Dis ' & $Drive) FileWrite($convertFile, @CRLF & 'convert mbr') FileClose($convertFile) $mainFile = FileOpen(@WorkingDir & '\cache\formatmain.dat', 2) FileWrite($mainFile, 'Sel Dis ' & $Drive) FileWrite($mainFile, @CRLF & 'cre par pri') FileWrite($mainFile, @CRLF & 'format quick fs=NTFS label=Windows') FileWrite($mainFile, @CRLF & 'Active') FileWrite($mainFile, @CRLF & 'Assign letter=' & $bootDrive) FileClose($mainFile) ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%") ProgressSet(20 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(30 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\scrub.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(40 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(50 & "%", "Resetting Disk Attributes") RunWait("cmd /c diskpart /s cache\attrib.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(60 & "%", "Converting Disk Layout to MBR") RunWait("cmd /c diskpart /s cache\convert.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(80 & "%", "Formatting Windows Partition") RunWait("cmd /c diskpart /s cache\formatmain.dat", @WorkingDir, @SW_HIDE) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatMBR Func _FormatGPT($Drive) _GetDriveLetters() GUISetState(@SW_HIDE) $cleandatFile = FileOpen(@WorkingDir & '\cache\clean.dat', 2) FileWrite($cleandatFile, 'Sel Dis ' & $Drive) FileWrite($cleandatFile, @CRLF & 'clean') FileClose($cleandatFile) $scrubdatFile = FileOpen(@WorkingDir & '\cache\scrub.dat', 2) FileWrite($scrubdatFile, 'Sel Dis ' & $Drive) FileWrite($scrubdatFile, @CRLF & 'cre par pri') FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=GPTscrubber') FileClose($scrubdatFile) $attribdatFile = FileOpen(@WorkingDir & '\cache\attrib.dat', 2) FileWrite($attribdatFile, 'Sel Dis ' & $Drive) FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly') FileClose($attribdatFile) $convertFile = FileOpen(@WorkingDir & '\cache\convert.dat', 2) FileWrite($convertFile, 'Sel Dis ' & $Drive) FileWrite($convertFile, @CRLF & 'convert gpt') FileClose($convertFile) $fsFile = FileOpen(@WorkingDir & '\cache\formatsystem.dat', 2) FileWrite($fsFile, 'Sel Dis ' & $Drive) FileWrite($fsFile, @CRLF & 'cre par efi size=100') FileWrite($fsFile, @CRLF & 'format quick fs=fat32 label=System') FileWrite($fsFile, @CRLF & 'assign letter=' & $bootDrive) FileClose($fsFile) $msrFile = FileOpen(@WorkingDir & '\cache\createmsr.dat', 2) FileWrite($msrFile, 'Sel Dis ' & $Drive) FileWrite($msrFile, @CRLF & 'cre par msr size=16') FileClose($msrFile) $mainFile = FileOpen(@WorkingDir & '\cache\formatmain.dat', 2) FileWrite($mainFile, 'Sel Dis ' & $Drive) FileWrite($mainFile, @CRLF & 'cre par pri') FileWrite($mainFile, @CRLF & 'shrink minimum=450') FileWrite($mainFile, @CRLF & 'format quick fs=ntfs label=Windows') FileWrite($mainFile, @CRLF & 'assign letter=' & $mainDrive) FileClose($mainFile) $reFile = FileOpen(@WorkingDir & '\cache\formatwinre.dat', 2) FileWrite($reFile, 'Sel Dis ' & $Drive) FileWrite($reFile, @CRLF & 'cre par pri') FileWrite($reFile, @CRLF & 'format quick fs=ntfs label=WinRE') FileWrite($reFile, @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac') FileClose($reFile) ProgressOn("Getting UEFI (GPT) Ready...","Preparing Disk: ", "0%") ProgressSet(10 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(15 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\scrub.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(20 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(30 & "%", "Resetting Disk Attributes") RunWait("cmd /c diskpart /s cache\attrib.dat", @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(40 & "%", "Converting Disk to GPT") RunWait("cmd /c diskpart /s cache\convert.dat", @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(50 & "%", "Formatting System Partition") RunWait("cmd /c diskpart /s cache\formatsystem.dat", @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(70 & "%", "Creating MSR") RunWait("cmd /c diskpart /s cache\createmsr.dat", @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(80 & "%", "Formatting Windows Partition") RunWait("cmd /c diskpart /s cache\formatmain.dat", @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(90 & "%", "Formatting WinRE Partition") RunWait("cmd /c diskpart /s cache\formatwinre.dat", @WorkingDir, @SW_HIDE) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatGPT Func _IniWriteMBR() IniWrite ( "..\WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":" ) IniWrite ( "..\WinNTSetup.ini", "WinNT6", "TempDest", $bootDrive & ":" ) IniWrite ( "..\WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":" ) IniWrite ( "..\WinNTSetup.ini", "WinNT5", "TempDest", $bootDrive & ":" ) EndFunc ;==>_IniWriteMBR Func _IniWriteGPT() IniWrite ( "..\WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":" ) IniWrite ( "..\WinNTSetup.ini", "WinNT6", "TempDest", $mainDrive & ":" ) IniWrite ( "..\WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":" ) IniWrite ( "..\WinNTSetup.ini", "WinNT5", "TempDest", $mainDrive & ":" ) EndFunc ;==>_IniWriteGPT Func _Cleanup() Local Const $WDcachePath = @WorkingDir & "\cache" If FileExists($WDcachePath) Then DirRemove($WDcachePath, $DIR_REMOVE) EndIf EndFunc ;==>_Cleanup Func _GetDriveLetters() Local $driveletter = StringSplit("Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C",",",1) For $bd = 1 to $driveletter[0] step +1 $bdStat = DriveStatus($driveletter[$bd] & ":") If $bdStat = "INVALID" Then $bootDrive=($driveletter[$bd]) For $md = 1 to $driveletter[0] step +1 $mdStat = DriveStatus($driveletter[$md] & ":") If Not ($bootDrive=($driveletter[$md])) Then If $mdStat = "INVALID" Then $mainDrive=($driveletter[$md]) EndIf EndIf Next EndIf Next EndFunc ;==>_GetDriveLetters very cool... and very much cleaned up from the OP Edited December 5, 2021 by bobomb
bobomb Posted December 5, 2021 Author Posted December 5, 2021 (edited) @benners i actually moved the _GetDriveLetters() call to the format functions. That way if someone opens the program the list is sitting open and someone plugs in a new disk this will wait until the format begins to check for available letters.. updated the post above to reflect this. Just some extra cleaning to ensure reliability. Edited December 5, 2021 by bobomb
benners Posted December 5, 2021 Posted December 5, 2021 AutoIt is a pretty lenient language compared to others, not that I have much experience with others but just from what I have read from other posts. In the future, you may want to learn another langauge so trying to incorporate best practice now could help later on. If a variable is modified from various points in the script, there isn't an issue with making it global but as was the case with $FIltered, does it need to be. Could it be local scope or passed ByRef. I have seen posts where people are having issues with code and they are expecting one value from a global variable but it is being changed elsewhere in a function as they have reused the variable name. When you create a variable it assigns a bit of memory to hold the value and though it's probably not an issue with todays ram sizes, but hogs memory if the variable isn't immediately required or may not be required when running the code. When your code gets more complex and too big for one file, you might start making UDFs of your own and keeping good structure and following naming conventions will make it easier when you come to troubleshoot issues. Have a peek inside the AutoIt UDFs and see how big things can get. When you declare variables outside of functions, AutoIt gives them a global scope. and some things benefit from this, liike a filepath. If you declare them inside functions using Local, the variable is destroyed when the function ends and the memory returned to the pool. If you had a massive array as global and this was only used in one function, it's a waste. I am sure others will add there knowledge about variables but a lot of times it's down to the individual and sometimes the size of the script whether its worth it. I try to give them scope and descriptive names as well as defining what value I am expecting on return. A read of the wiki will explain more in depth than I have. bobomb 1
benners Posted December 5, 2021 Posted December 5, 2021 I'm glad you're tweaking it, It's addictive after a while. I have wasted loads of time overthinking code rather than coding first then tweaking. With loops, a variable is created automatically with the local scope so you don't need to declare it. In your instance $RawList doesn't need to be declared. I normaly use $i for a count variable so, For $i = 1 To 5 ' code here Next In previous code it was declared as a global variable. I see now you have move it to the GetInfo function 👍. Once the code is working as you want, it would be a good idea to add some error checking. An example would be checking an array is an array before performing actions on it., or checking file read\close operations, if they are essential. More tweaks for later would be to change the do loop to a while loop, use a switch or select case instead of the if..then parts, and move the code currently inside the if..then into their own functions 😀
junkew Posted December 5, 2021 Posted December 5, 2021 (edited) Using global variables you learned already by hitting a defect with the list. Think twice when you introduce globals its fine when you have small scripts. But a rule of thumb "Do I understand next month still what I have written" or "Does someone else understand it by reading it 1 time" This expandcollapse popupFunc _FormatMBR($Drive) _GetDriveLetters() GUISetState(@SW_HIDE) $cleandatFile = FileOpen(@WorkingDir & '\cache\clean.dat', 2) FileWrite($cleandatFile, 'Sel Dis ' & $Drive) FileWrite($cleandatFile, @CRLF & 'clean') FileClose($cleandatFile) $attribdatFile = FileOpen(@WorkingDir & '\cache\attrib.dat', 2) FileWrite($attribdatFile, 'Sel Dis ' & $Drive) FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly') FileClose($attribdatFile) $scrubdatFile = FileOpen(@WorkingDir & '\cache\scrub.dat', 2) FileWrite($scrubdatFile, 'Sel Dis ' & $Drive) FileWrite($scrubdatFile, @CRLF & 'cre par pri') FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=MBRscrubber') FileClose($scrubdatFile) $convertFile = FileOpen(@WorkingDir & '\cache\convert.dat', 2) FileWrite($convertFile, 'Sel Dis ' & $Drive) FileWrite($convertFile, @CRLF & 'convert mbr') FileClose($convertFile) $mainFile = FileOpen(@WorkingDir & '\cache\formatmain.dat', 2) FileWrite($mainFile, 'Sel Dis ' & $Drive) FileWrite($mainFile, @CRLF & 'cre par pri') FileWrite($mainFile, @CRLF & 'format quick fs=NTFS label=Windows') FileWrite($mainFile, @CRLF & 'Active') FileWrite($mainFile, @CRLF & 'Assign letter=' & $bootDrive) FileClose($mainFile) ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%") ProgressSet(20 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(30 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\scrub.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(40 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(50 & "%", "Resetting Disk Attributes") RunWait("cmd /c diskpart /s cache\attrib.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(60 & "%", "Converting Disk Layout to MBR") RunWait("cmd /c diskpart /s cache\convert.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(80 & "%", "Formatting Windows Partition") RunWait("cmd /c diskpart /s cache\formatmain.dat", @WorkingDir, @SW_HIDE) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatMBR you could rewrite for "Clean coding" like below expandcollapse popupfunc _writeInfoToFile($fileName, $message) $cleandatFile = FileOpen($fileName, 2) FileWrite($cleandatFile, $message) FileClose($cleandatFile) end func func _cleanDrive() ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%") ProgressSet(20 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) end func func cleanDrive2()\ ProgressSet(40 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\clean.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) end func func _scrubDrive() ProgressSet(30 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s cache\scrub.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) end func func _resetDrive() ProgressSet(50 & "%", "Resetting Disk Attributes") RunWait("cmd /c diskpart /s cache\attrib.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) end func func _convertDrive() ProgressSet(60 & "%", "Converting Disk Layout to MBR") RunWait("cmd /c diskpart /s cache\convert.dat", @WorkingDir, @SW_HIDE) SLEEP(1000) end func func formatWindowsPartition() ProgressSet(80 & "%", "Formatting Windows Partition") RunWait("cmd /c diskpart /s cache\formatmain.dat", @WorkingDir, @SW_HIDE) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) end func Func _FormatMBR($Drive) _GetDriveLetters() GUISetState(@SW_HIDE) _writeInfoToFile(@WorkingDir & '\cache\clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean') _writeInfoToFile(@WorkingDir & '\cache\scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & 'format quick fs=NTFS label=MBRscrubber' ) _writeInfoToFile(@WorkingDir & '\cache\convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr') _writeInfoToFile(@WorkingDir & '\cache\formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' @CRLF & 'Active' @CRLF & 'Assign letter=' & $bootDrive) _cleanDrive1() _scrubDrive() _cleanDrive2() _resetDrive() _convertDrive() _formatWindowsPartition() ProgressOff() GUISetState() EndFunc ;==>_FormatMBR Edited December 5, 2021 by junkew FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
bobomb Posted December 5, 2021 Author Posted December 5, 2021 (edited) @junkew literally was just cleaning that expandcollapse popup#NoTrayIcon #RequireAdmin #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=PrepareDiskNT.ico #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Res_Comment=Place in a subfolder to WinNTSetup5 (e.g. C:\WinNTSetup5\Prep) #AutoIt3Wrapper_Res_Description=PrepareDiskNT for WinNTSetup5 #AutoIt3Wrapper_Res_Fileversion=1.3 #AutoIt3Wrapper_Add_Constants=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <ListBoxConstants.au3> #include <Constants.au3> #include <File.au3> #include <Array.au3> #include <String.au3> Global $WinNTSetupPath = (@WorkingDir & "\..\") ;To run in the same folder as WinNTSetup5 instead of subfolder just use "\" instead of "\..\" Global $CachePath = (@WorkingDir & "\cache\") Global $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive _Cleanup() DirCreate($CachePath) $listFile = FileOpen($CachePath & 'list.ini', 2) FileWrite($listFile, 'lis dis') FileClose($listFile) GUICreate('Prep/Format Disk v1.3', 300, 298) GUISetIcon (@WorkingDir & '\PrepareDiskNT.ico',1) GUISetBkColor (0x797979) GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280) $DiskList = GUICtrlCreateList('', 20, 30, 260, 150) GUICtrlSetData(-1, _DiskList()) $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25) GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30) $MBR = GUICtrlCreateButton('BIOS (MBR) Boot',20, 232, 120, 40) $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40) GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30) GUISetState() Do $Selection = GUIGetMsg() If $Selection = $MBR Then Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $iMsgBoxAnswer If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $iMsgBoxAnswer = 6 ;Yes _FormatMBR($DiskN[6]) _IniWriteMBR() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive) Run("cmd /c " & $WinNTSetupPath & "WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE) _Cleanup() Exit Case $iMsgBoxAnswer = 7 ;No EndSelect EndIf EndIf If $Selection = $GPT Then Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $iMsgBoxAnswer If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $iMsgBoxAnswer = 6 ;Yes _FormatGPT($DiskN[6]) _IniWriteGPT() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive) Run("cmd /c " & $WinNTSetupPath & "WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE) _Cleanup() Exit Case $iMsgBoxAnswer = 7 ;No EndSelect EndIf EndIf If $Selection = $Refresh Then GUICtrlSetData($DiskList, "") GUICtrlSetData($DiskList, _DiskList()) EndIf Until $Selection = $GUI_EVENT_CLOSE _Cleanup() Func _DiskList() RunWait("cmd /c diskpart /s " & $CachePath & "list.ini>" & $CachePath & "list.txt", @WorkingDir, @SW_HIDE) Local $Filtered = '', $RawList, $Array = _StringExplode(FileRead($CachePath & 'list.txt'), @LF) For $RawList = 0 To UBound($Array) - 1 If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|' Next $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '') Return $Filtered EndFunc ;==>_DiskList Func _FormatMBR($Drive) _GetDriveLetters() GUISetState(@SW_HIDE) $cleandatFile = FileOpen($CachePath & 'clean.dat', 2) FileWrite($cleandatFile, 'Sel Dis ' & $Drive) FileWrite($cleandatFile, @CRLF & 'clean') FileClose($cleandatFile) $scrubdatFile = FileOpen($CachePath & 'scrub.dat', 2) FileWrite($scrubdatFile, 'Sel Dis ' & $Drive) FileWrite($scrubdatFile, @CRLF & 'cre par pri') FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=MBRscrubber') FileClose($scrubdatFile) $attribdatFile = FileOpen($CachePath & 'attrib.dat', 2) FileWrite($attribdatFile, 'Sel Dis ' & $Drive) FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly') FileClose($attribdatFile) $convertFile = FileOpen($CachePath & 'convert.dat', 2) FileWrite($convertFile, 'Sel Dis ' & $Drive) FileWrite($convertFile, @CRLF & 'convert mbr') FileClose($convertFile) $mainFile = FileOpen($CachePath & 'formatmain.dat', 2) FileWrite($mainFile, 'Sel Dis ' & $Drive) FileWrite($mainFile, @CRLF & 'cre par pri') FileWrite($mainFile, @CRLF & 'format quick fs=NTFS label=Windows') FileWrite($mainFile, @CRLF & 'Active') FileWrite($mainFile, @CRLF & 'Assign letter=' & $bootDrive) FileClose($mainFile) ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%") ProgressSet(20 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(30 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'scrub.dat', @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(40 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(50 & "%", "Resetting Disk Attributes") RunWait("cmd /c diskpart /s " & $CachePath & 'attrib.dat', @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(60 & "%", "Converting Disk Layout to MBR") RunWait("cmd /c diskpart /s " & $CachePath & 'convert.dat', @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(80 & "%", "Formatting Windows Partition") RunWait("cmd /c diskpart /s " & $CachePath & 'formatmain.dat', @WorkingDir, @SW_HIDE) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatMBR Func _FormatGPT($Drive) _GetDriveLetters() GUISetState(@SW_HIDE) $cleandatFile = FileOpen($CachePath & 'clean.dat', 2) FileWrite($cleandatFile, 'Sel Dis ' & $Drive) FileWrite($cleandatFile, @CRLF & 'clean') FileClose($cleandatFile) $scrubdatFile = FileOpen($CachePath & 'scrub.dat', 2) FileWrite($scrubdatFile, 'Sel Dis ' & $Drive) FileWrite($scrubdatFile, @CRLF & 'cre par pri') FileWrite($scrubdatFile, @CRLF & 'format quick fs=NTFS label=GPTscrubber') FileClose($scrubdatFile) $attribdatFile = FileOpen($CachePath & 'attrib.dat', 2) FileWrite($attribdatFile, 'Sel Dis ' & $Drive) FileWrite($attribdatFile, @CRLF & 'attribute disk clear readonly') FileClose($attribdatFile) $convertFile = FileOpen($CachePath & 'convert.dat', 2) FileWrite($convertFile, 'Sel Dis ' & $Drive) FileWrite($convertFile, @CRLF & 'convert gpt') FileClose($convertFile) $fsFile = FileOpen($CachePath & 'formatsystem.dat', 2) FileWrite($fsFile, 'Sel Dis ' & $Drive) FileWrite($fsFile, @CRLF & 'cre par efi size=100') FileWrite($fsFile, @CRLF & 'format quick fs=fat32 label=System') FileWrite($fsFile, @CRLF & 'assign letter=' & $bootDrive) FileClose($fsFile) $msrFile = FileOpen($CachePath & 'createmsr.dat', 2) FileWrite($msrFile, 'Sel Dis ' & $Drive) FileWrite($msrFile, @CRLF & 'cre par msr size=16') FileClose($msrFile) $mainFile = FileOpen($CachePath & 'formatmain.dat', 2) FileWrite($mainFile, 'Sel Dis ' & $Drive) FileWrite($mainFile, @CRLF & 'cre par pri') FileWrite($mainFile, @CRLF & 'shrink minimum=450') FileWrite($mainFile, @CRLF & 'format quick fs=ntfs label=Windows') FileWrite($mainFile, @CRLF & 'assign letter=' & $mainDrive) FileClose($mainFile) $reFile = FileOpen($CachePath & 'formatwinre.dat', 2) FileWrite($reFile, 'Sel Dis ' & $Drive) FileWrite($reFile, @CRLF & 'cre par pri') FileWrite($reFile, @CRLF & 'format quick fs=ntfs label=WinRE') FileWrite($reFile, @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac') FileClose($reFile) ProgressOn("Getting UEFI (GPT) Ready...","Preparing Disk: ", "0%") ProgressSet(10 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(15 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'scrub.dat', @WorkingDir, @SW_HIDE) SLEEP(1000) ProgressSet(20 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(30 & "%", "Resetting Disk Attributes") RunWait("cmd /c diskpart /s " & $CachePath & 'attrib.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(40 & "%", "Converting Disk to GPT") RunWait("cmd /c diskpart /s " & $CachePath & 'convert.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(50 & "%", "Formatting System Partition") RunWait("cmd /c diskpart /s " & $CachePath & 'formatsystem.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(70 & "%", "Creating MSR") RunWait("cmd /c diskpart /s " & $CachePath & 'createmsr.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(80 & "%", "Formatting Windows Partition") RunWait("cmd /c diskpart /s " & $CachePath & 'formatmain.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(90 & "%", "Formatting WinRE Partition") RunWait("cmd /c diskpart /s " & $CachePath & 'formatwinre.dat', @WorkingDir, @SW_HIDE) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatGPT Func _IniWriteMBR() IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "TempDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "TempDest", $bootDrive & ":" ) EndFunc ;==>_IniWriteMBR Func _IniWriteGPT() IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "TempDest", $mainDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "TempDest", $mainDrive & ":" ) EndFunc ;==>_IniWriteGPT Func _Cleanup() If FileExists($CachePath) Then DirRemove($CachePath, $DIR_REMOVE) EndIf EndFunc ;==>_Cleanup Func _GetDriveLetters() Local $driveletter = StringSplit("Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C",",",1) For $bd = 1 to $driveletter[0] step +1 $bdStat = DriveStatus($driveletter[$bd] & ":") If $bdStat = "INVALID" Then $bootDrive=($driveletter[$bd]) For $md = 1 to $driveletter[0] step +1 $mdStat = DriveStatus($driveletter[$md] & ":") If Not ($bootDrive=($driveletter[$md])) Then If $mdStat = "INVALID" Then $mainDrive=($driveletter[$md]) EndIf EndIf Next EndIf Next EndFunc ;==>_GetDriveLetters But I still have a ways to go.. Edited December 5, 2021 by bobomb
bobomb Posted December 5, 2021 Author Posted December 5, 2021 I know I am trying to use less globals, they are temporary Im proly gonna have it read from a settings ini in its own folder for these paths later.
junkew Posted December 5, 2021 Posted December 5, 2021 I just was editing my post with some rewritten code, see my previous post for some refactored code. "general rule of thumb" functions should not have more then 10-20 lines of code but split frequently and give your function a meaningfull name describing your intent. The more you do that the less comments you will need in your coding. bobomb 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
junkew Posted December 5, 2021 Posted December 5, 2021 Study this one https://www.autoitscript.com/autoit3/docs/functions/GUICtrlSetOnEvent.htm You can put your gui in function a and by setting the events you can give each event a different function. This split will make your life easier in maintenance and shows clearly the intent of each action you want to do by splitting GUI from the actual functionality away. And if you really want to learn more there are offcourse many references on the internet but this is a nice list of some good practices https://gist.github.com/wojteklu/73c6914cc446146b8b533c0988cf8d29#file-clean_code-md bobomb 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
bobomb Posted December 5, 2021 Author Posted December 5, 2021 (edited) Halfway there, not sure how i want to break down the format functions yet.. expandcollapse popup#NoTrayIcon #RequireAdmin #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=PrepareDiskNT.ico #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Res_Comment=Place in a subfolder to WinNTSetup5 (e.g. C:\WinNTSetup5\Prep) #AutoIt3Wrapper_Res_Description=PrepareDiskNT for WinNTSetup5 #AutoIt3Wrapper_Res_Fileversion=1.3 #AutoIt3Wrapper_Add_Constants=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <ListBoxConstants.au3> #include <Constants.au3> #include <File.au3> #include <Array.au3> #include <String.au3> Global $WinNTSetupPath = (@WorkingDir & "\") ;To run in the same folder as WinNTSetup5 instead of subfolder just use "\" instead of "\..\" Global $CachePath = (@WorkingDir & "\cache\") Global $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive _Cleanup() DirCreate($CachePath) $listFile = FileOpen($CachePath & 'list.ini', 2) FileWrite($listFile, 'lis dis') FileClose($listFile) GUICreate('Prep/Format Disk v1.3', 300, 298) GUISetIcon (@WorkingDir & '\PrepareDiskNT.ico',1) GUISetBkColor (0x797979) GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280) $DiskList = GUICtrlCreateList('', 20, 30, 260, 150) GUICtrlSetData(-1, _DiskList()) $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25) GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30) $MBR = GUICtrlCreateButton('BIOS (MBR) Boot',20, 232, 120, 40) $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40) GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30) GUISetState() Do $Selection = GUIGetMsg() If $Selection = $MBR Then Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $iMsgBoxAnswer If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $iMsgBoxAnswer = 6 ;Yes _FormatMBR($DiskN[6]) _IniWriteMBR() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive) Run("cmd /c " & $WinNTSetupPath & "WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE) _Cleanup() Exit Case $iMsgBoxAnswer = 7 ;No EndSelect EndIf EndIf If $Selection = $GPT Then Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $iMsgBoxAnswer If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $iMsgBoxAnswer = 6 ;Yes _FormatGPT($DiskN[6]) _IniWriteGPT() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive) Run("cmd /c " & $WinNTSetupPath & "WinNTSetup_x64.exe", @WorkingDir, @SW_HIDE) _Cleanup() Exit Case $iMsgBoxAnswer = 7 ;No EndSelect EndIf EndIf If $Selection = $Refresh Then GUICtrlSetData($DiskList, "") GUICtrlSetData($DiskList, _DiskList()) EndIf Until $Selection = $GUI_EVENT_CLOSE _Cleanup() Func _DiskList() RunWait("cmd /c diskpart /s " & $CachePath & "list.ini>" & $CachePath & "list.txt", @WorkingDir, @SW_HIDE) Local $Filtered = '', $RawList, $Array = _StringExplode(FileRead($CachePath & 'list.txt'), @LF) For $RawList = 0 To UBound($Array) - 1 If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|' Next $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '') Return $Filtered EndFunc ;==>_DiskList Func _FormatMBR($Drive) _GetDriveLetters() _writeInfoToFile($CachePath & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean') _writeInfoToFile($CachePath & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=MBRscrubber') _writeInfoToFile($CachePath & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly') _writeInfoToFile($CachePath & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr') _writeInfoToFile($CachePath & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' & @CRLF & 'Active' & @CRLF & 'Assign letter=' & $bootDrive) GUISetState(@SW_HIDE) ProgressOn("Getting BIOS (MBR) Ready...","Preparing Disk: ", "0%") ProgressSet(20 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(30 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'scrub.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(40 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(50 & "%", "Resetting Disk Attributes") RunWait("cmd /c diskpart /s " & $CachePath & 'attrib.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(60 & "%", "Converting Disk Layout to MBR") RunWait("cmd /c diskpart /s " & $CachePath & 'convert.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(80 & "%", "Formatting Windows Partition") RunWait("cmd /c diskpart /s " & $CachePath & 'formatmain.dat', @WorkingDir, @SW_HIDE) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatMBR Func _FormatGPT($Drive) _GetDriveLetters() _writeInfoToFile($CachePath & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean') _writeInfoToFile($CachePath & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=GPTscrubber') _writeInfoToFile($CachePath & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly') _writeInfoToFile($CachePath & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert gpt') _writeInfoToFile($CachePath & 'formatsystem.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par efi size=100' & @CRLF & 'format quick fs=fat32 label=System' & @CRLF & 'assign letter=' & $bootDrive) _writeInfoToFile($CachePath & 'createmsr.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par msr size=16') _writeInfoToFile($CachePath & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=450' & @CRLF & 'format quick fs=ntfs label=Windows' & @CRLF & 'assign letter=' & $mainDrive) _writeInfoToFile($CachePath & 'formatwinre.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=ntfs label=WinRE' & @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac') GUISetState(@SW_HIDE) ProgressOn("Getting UEFI (GPT) Ready...","Preparing Disk: ", "0%") ProgressSet(10 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(15 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'scrub.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(20 & "%", "Cleaning Drive") RunWait("cmd /c diskpart /s " & $CachePath & 'clean.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(30 & "%", "Resetting Disk Attributes") RunWait("cmd /c diskpart /s " & $CachePath & 'attrib.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(40 & "%", "Converting Disk to GPT") RunWait("cmd /c diskpart /s " & $CachePath & 'convert.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(50 & "%", "Formatting System Partition") RunWait("cmd /c diskpart /s " & $CachePath & 'formatsystem.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(70 & "%", "Creating MSR") RunWait("cmd /c diskpart /s " & $CachePath & 'createmsr.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(80 & "%", "Formatting Windows Partition") RunWait("cmd /c diskpart /s " & $CachePath & 'formatmain.dat', @WorkingDir, @SW_HIDE) Sleep(1000) ProgressSet(90 & "%", "Formatting WinRE Partition") RunWait("cmd /c diskpart /s " & $CachePath & 'formatwinre.dat', @WorkingDir, @SW_HIDE) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatGPT Func _writeInfoToFile($fileName, $message) $CacheFile = '' $CacheFile = FileOpen($fileName, 2) FileWrite($CacheFile, $message) FileClose($CacheFile) EndFunc Func _IniWriteMBR() IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "TempDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "TempDest", $bootDrive & ":" ) EndFunc ;==>_IniWriteMBR Func _IniWriteGPT() IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "TempDest", $mainDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":" ) IniWrite ($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "TempDest", $mainDrive & ":" ) EndFunc ;==>_IniWriteGPT Func _Cleanup() If FileExists($CachePath) Then DirRemove($CachePath, $DIR_REMOVE) EndIf EndFunc ;==>_Cleanup Func _GetDriveLetters() Local $driveletter = StringSplit("Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C",",",1) For $bd = 1 to $driveletter[0] step +1 $bdStat = DriveStatus($driveletter[$bd] & ":") If $bdStat = "INVALID" Then $bootDrive=($driveletter[$bd]) For $md = 1 to $driveletter[0] step +1 $mdStat = DriveStatus($driveletter[$md] & ":") If Not ($bootDrive=($driveletter[$md])) Then If $mdStat = "INVALID" Then $mainDrive=($driveletter[$md]) EndIf EndIf Next EndIf Next EndFunc ;==>_GetDriveLetters Edited December 5, 2021 by bobomb
bobomb Posted December 5, 2021 Author Posted December 5, 2021 (edited) The variable paths I added introduced issues with paths with spaces, but I corrected it below, I also reduced the sleep times as they arent even needed (verified through testing) but it freaks me out when i jam that many commands at diskpart, even though it works i still dont trust it without letting it breathe a little.. officially you are supposed to wait 15 seconds between each diskpart script 😜 expandcollapse popup#NoTrayIcon #RequireAdmin #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=PrepareDiskNT.ico #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Res_Comment=Place in a subfolder to WinNTSetup5 (e.g. C:\WinNTSetup5\Prep) #AutoIt3Wrapper_Res_Description=PrepareDiskNT for WinNTSetup5 #AutoIt3Wrapper_Res_Fileversion=1.3.0.0 #AutoIt3Wrapper_Add_Constants=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <ListBoxConstants.au3> #include <Constants.au3> #include <File.au3> #include <Array.au3> #include <String.au3> Global $WinNTSetupPath = (@WorkingDir & '\..\') ;To run in the same folder as WinNTSetup5 use "\" for subfolder use "\..\" Global $CachePath = (@WorkingDir & '\cache\') Global $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive _Cleanup() DirCreate($CachePath) $listFile = FileOpen($CachePath & 'list.ini', 2) FileWrite($listFile, 'lis dis') FileClose($listFile) GUICreate('Prep/Format Disk v1.3', 300, 298) GUISetIcon(@WorkingDir & '\PrepareDiskNT.ico', 1) GUISetBkColor(0x797979) GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280) $DiskList = GUICtrlCreateList('', 20, 30, 260, 150) GUICtrlSetData(-1, _DiskList()) $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25) GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30) $MBR = GUICtrlCreateButton('BIOS (MBR) Boot', 20, 232, 120, 40) $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40) GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30) GUISetState() Do $Selection = GUIGetMsg() If $Selection = $MBR Then Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $iMsgBoxAnswer If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $iMsgBoxAnswer = 6 ;Yes _PrepMBR($DiskN[6]) _FormatMBR() _IniWriteMBR() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive) _LaunchWinNTSetup() _Cleanup() Exit Case $iMsgBoxAnswer = 7 ;No EndSelect EndIf EndIf If $Selection = $GPT Then Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $iMsgBoxAnswer If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $iMsgBoxAnswer = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $iMsgBoxAnswer = 6 ;Yes _PrepGPT($DiskN[6]) _FormatGPT() _IniWriteGPT() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive) _LaunchWinNTSetup() _Cleanup() Exit Case $iMsgBoxAnswer = 7 ;No EndSelect EndIf EndIf If $Selection = $Refresh Then GUICtrlSetData($DiskList, "") GUICtrlSetData($DiskList, _DiskList()) EndIf Until $Selection = $GUI_EVENT_CLOSE _Cleanup() Func _DiskList() RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'list.ini' & '"' & '>' & '"' & $CachePath & 'list.txt' & '"', @WorkingDir, @SW_HIDE) Local $Filtered = '', $RawList, $Array = _StringExplode(FileRead($CachePath & 'list.txt'), @LF) For $RawList = 0 To UBound($Array) - 1 If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|' Next $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '') Return $Filtered EndFunc ;==>_DiskList Func _PrepMBR($Drive) _GetDriveLetters() _writeInfoToFile($CachePath & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean') _writeInfoToFile($CachePath & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=MBRscrubber') _writeInfoToFile($CachePath & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly') _writeInfoToFile($CachePath & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr') _writeInfoToFile($CachePath & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' & @CRLF & 'Active' & @CRLF & 'Assign letter=' & $bootDrive) EndFunc ;==>_PrepMBR Func _PrepGPT($Drive) _GetDriveLetters() _writeInfoToFile($CachePath & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean') _writeInfoToFile($CachePath & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=GPTscrubber') _writeInfoToFile($CachePath & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly') _writeInfoToFile($CachePath & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert gpt') _writeInfoToFile($CachePath & 'formatsystem.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par efi size=100' & @CRLF & 'format quick fs=fat32 label=System' & @CRLF & 'assign letter=' & $bootDrive) _writeInfoToFile($CachePath & 'createmsr.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par msr size=16') _writeInfoToFile($CachePath & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=450' & @CRLF & 'format quick fs=ntfs label=Windows' & @CRLF & 'assign letter=' & $mainDrive) _writeInfoToFile($CachePath & 'formatwinre.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=ntfs label=WinRE' & @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac') EndFunc ;==>_PrepGPT Func _GetDriveLetters() Local $driveletter = StringSplit("Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C", ",", 1) For $bd = 1 To $driveletter[0] Step +1 $bdStat = DriveStatus($driveletter[$bd] & ":") If $bdStat = "INVALID" Then $bootDrive = ($driveletter[$bd]) For $md = 1 To $driveletter[0] Step +1 $mdStat = DriveStatus($driveletter[$md] & ":") If Not ($bootDrive = ($driveletter[$md])) Then If $mdStat = "INVALID" Then $mainDrive = ($driveletter[$md]) EndIf EndIf Next EndIf Next EndFunc ;==>_GetDriveLetters Func _writeInfoToFile($fileName, $message) $CacheFile = '' $CacheFile = FileOpen($fileName, 2) FileWrite($CacheFile, $message) FileClose($CacheFile) EndFunc ;==>_writeInfoToFile Func _IniWriteMBR() IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "TempDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "TempDest", $bootDrive & ":") EndFunc ;==>_IniWriteMBR Func _IniWriteGPT() IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "TempDest", $mainDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "TempDest", $mainDrive & ":") EndFunc ;==>_IniWriteGPT Func _LaunchWinNTSetup() Run('cmd /c ' & '"' & $WinNTSetupPath & 'WinNTSetup_x64.exe' & '"', @WorkingDir, @SW_HIDE) EndFunc Func _Cleanup() If FileExists($CachePath) Then DirRemove($CachePath, $DIR_REMOVE) EndIf EndFunc ;==>_Cleanup Func _FormatMBR() GUISetState(@SW_HIDE) ProgressOn("Getting BIOS (MBR) Ready...", "Preparing Disk: ", "0%") ProgressSet(20 & "%", "Cleaning Drive") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(30 & "%", "Cleaning Drive") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'scrub.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(40 & "%", "Cleaning Drive") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(50 & "%", "Resetting Disk Attributes") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'attrib.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(60 & "%", "Converting Disk Layout to MBR") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'convert.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(80 & "%", "Formatting Windows Partition") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'formatmain.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc Func _FormatGPT() GUISetState(@SW_HIDE) ProgressOn("Getting UEFI (GPT) Ready...", "Preparing Disk: ", "0%") ProgressSet(10 & "%", "Cleaning Drive") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(15 & "%", "Cleaning Drive") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'scrub.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(20 & "%", "Cleaning Drive") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(30 & "%", "Resetting Disk Attributes") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'attrib.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(40 & "%", "Converting Disk to GPT") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'convert.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(50 & "%", "Formatting System Partition") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'formatsystem.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(70 & "%", "Creating MSR") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'createmsr.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(80 & "%", "Formatting Windows Partition") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'formatmain.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(90 & "%", "Formatting WinRE Partition") RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'formatwinre.dat' & '"', @WorkingDir, @SW_HIDE) Sleep(500) ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatGPT Edited December 6, 2021 by bobomb
junkew Posted December 6, 2021 Posted December 6, 2021 Now I understand a little more from your script rename _writeInfoToFile to _createDiskPartScriptFile as thats what you are actually doing Some example of more refactoring with multidimensional array you have to uncomment the runwait command and the percentage calculation you can improve by (%i/ubound($aarray) * 100) The more you split and refactor the easier it becomes for debugging and testing besides the benefit of readability and maintainability _formatGPT() Func _FormatGPT() GUISetState(@SW_HIDE) local $aArray[9][3] = [ _ ["Cleaning Drive" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"'], _ ["Cleaning Drive" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'scrub.dat' & '"'], _ ["Cleaning Drive" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"'], _ ["Resetting Disk Attributes" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'attrib.dat' & '"'], _ ["Converting Disk to GPT" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'convert.dat' & '"'], _ ["Formatting System Partition" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'formatsystem.dat' & '"'], _ ["Formatting Windows Partition" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'createmsr.dat' & '"'], _ ["Formatting WinRE Partition" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'formatmain.dat' & '"'], _ ["Formatting WinRE Partition" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'formatwinre.dat' & '"'] _ ] ProgressOn("Getting UEFI (GPT) Ready...", "Preparing Disk: ", "0%") for $i=0 to ubound($aArray)-1 consolewrite($aArray[$i][1] & @CRLF) ProgressSet($i*10 & "%", $aArray[$i][0]) ; RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE) Sleep(500) Next ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc Example to put your GUI in event mode will clean up even more expandcollapse popupOpt("GUIOnEventMode", 1) myGui() func myGui() GUICreate('Prep/Format Disk v1.3', 300, 298) GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents") GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents") GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents") GUISetIcon(@WorkingDir & '\PrepareDiskNT.ico', 1) GUISetBkColor(0x797979) GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280) $DiskList = GUICtrlCreateList('', 20, 30, 260, 150) GUICtrlSetData(-1, _DiskList()) $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25) GUICtrlSetOnEvent(-1, "RefreshPressed") GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30) $MBR = GUICtrlCreateButton('BIOS (MBR) Boot', 20, 232, 120, 40) GUICtrlSetOnEvent(-1, "MBRPressed") $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40) GUICtrlSetOnEvent(-1, "GFTPressed") GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30) GUISetState() ; Just idle around While 1 Sleep(10) WEnd EndFunc Func RefreshPressed() MsgBox($MB_SYSTEMMODAL, "RefreshPressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle) EndFunc ;==>OKPressed Func MBRPressed() MsgBox($MB_SYSTEMMODAL, "MBRPressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle) EndFunc ;==>OKPressed Func GFTPressed() MsgBox($MB_SYSTEMMODAL, "GFTPressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle) EndFunc ;==>CancelPressed Func SpecialEvents() Select Case @GUI_CtrlId = $GUI_EVENT_CLOSE MsgBox($MB_SYSTEMMODAL, "Close Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle) Exit Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE MsgBox($MB_SYSTEMMODAL, "Window Minimized", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle) Case @GUI_CtrlId = $GUI_EVENT_RESTORE MsgBox($MB_SYSTEMMODAL, "Window Restored", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle) EndSelect EndFunc ;==>SpecialEvents bobomb 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
bobomb Posted December 7, 2021 Author Posted December 7, 2021 (edited) @junkew Here is the updated script with your recommendations added. expandcollapse popup#NoTrayIcon #RequireAdmin #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <ListBoxConstants.au3> #include <Constants.au3> #include <File.au3> #include <Array.au3> #include <String.au3> Global $WinNTSetupPath, $CachePath, $DiskList, $Selection, $MBR, $GPT, $Refresh, $bootDrive, $mainDrive _GetCachePath() _GetWinNTSetupPath() _Cleanup() DirCreate($CachePath) $listFile = FileOpen($CachePath & 'list.ini', 2) FileWrite($listFile, 'lis dis') FileClose($listFile) Opt("GUIOnEventMode", 1) _MainMenu() _Cleanup() Exit Func _MainMenu() GUICreate('Prep/Format Disk v1.3', 300, 298) GUISetOnEvent($GUI_EVENT_CLOSE, "_SpecialEvents") GUISetOnEvent($GUI_EVENT_MINIMIZE, "_SpecialEvents") GUISetOnEvent($GUI_EVENT_RESTORE, "_SpecialEvents") GUISetIcon(@WorkingDir & '\PrepareDiskNT.ico', 1) GUISetBkColor(0x797979) GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280) $DiskList = GUICtrlCreateList('', 20, 30, 260, 150) GUICtrlSetData(-1, _DiskList()) $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25) GUICtrlSetOnEvent(-1, "_RefreshPressed") GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30) $MBR = GUICtrlCreateButton('BIOS (MBR) Boot', 20, 232, 120, 40) GUICtrlSetOnEvent(-1, "_MBRPressed") $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 232, 120, 40) GUICtrlSetOnEvent(-1, "_GPTPressed") GUICtrlCreateLabel('( * ) Disk is Currently GPT', 160, 278, 130, 30) GUISetState() ; Just idle around While 1 Sleep(10) WEnd EndFunc ;==>_MainMenu Func _RefreshPressed() GUICtrlSetData($DiskList, "") GUICtrlSetData($DiskList, _DiskList()) EndFunc ;==>_RefreshPressed Func _MBRPressed() Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $AreYouSure If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $AreYouSure = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $AreYouSure = 6 ;Yes _PrepMBR($DiskN[6]) _FormatMBR() _IniWriteMBR() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive) _LaunchWinNTSetup() _Cleanup() Exit Case $AreYouSure = 7 ;No EndSelect EndIf EndFunc ;==>MBRPressed Func _GPTPressed() Local $Disk = StringRegExpReplace(GUICtrlRead($DiskList), '(?i)^.*(Disk [\d]+).*$', '$1') Local $DiskN = StringSplit($Disk, "") Local $AreYouSure If $Disk = "" Then MsgBox($MB_ICONERROR, "Notice: ", "No disk has been selected") Else $AreYouSure = MsgBox(262452, 'This will FORMAT Disk ' & $DiskN[6], 'ALL DATA WILL BE ERASED FROM ' & 'DISK ' & $DiskN[6] & @CRLF & 'Are you sure you want to proceed?') Select Case $AreYouSure = 6 ;Yes _PrepGPT($DiskN[6]) _FormatGPT() _IniWriteGPT() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive) _LaunchWinNTSetup() _Cleanup() Exit Case $AreYouSure = 7 ;No EndSelect EndIf EndFunc ;==>_GPTPressed Func _SpecialEvents() Select Case @GUI_CtrlId = $GUI_EVENT_CLOSE ; Code below for actions on Close _Cleanup() Exit Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE ; Code below for actions on Minimize Case @GUI_CtrlId = $GUI_EVENT_RESTORE ; Code below for actions on Restore EndSelect EndFunc ;==>_SpecialEvents Func _DiskList() RunWait('cmd /c diskpart /s ' & '"' & $CachePath & 'list.ini' & '"' & '>' & '"' & $CachePath & 'list.txt' & '"', @WorkingDir, @SW_HIDE) Local $Filtered = '', $Array = _StringExplode(FileRead($CachePath & 'list.txt'), @LF) For $RawList = 0 To UBound($Array) - 1 If StringRegExp($Array[$RawList], '(?i)Disk [\d]+') Then $Filtered &= $Array[$RawList] & '|' Next $Filtered = StringRegExpReplace($Filtered, '[\s|]*$', '') Return $Filtered EndFunc ;==>_DiskList Func _GetDriveLetters() Local $allDriveLetters="CDEFGHIJKLMNOPQRSTUVWXYZ", $AvailDriveLetters Local $aArray = DriveGetDrive($DT_ALL) If @error Then ; An error occurred when retrieving the drives. MsgBox($MB_SYSTEMMODAL, "", "An Error Occurred! Unable to retrieve " & @CRLF & "available drive letters! Exiting Program...") _Cleanup() Exit Else For $i = 1 To $aArray[0] $driveLetter=stringleft(StringUpper($aArray[$i]),1) $allDriveLetters=stringreplace($allDriveLetters,$driveLetter,"") Next EndIf $AvailDriveLetters = StringSplit($allDriveLetters,"") $bootDrive = $AvailDriveLetters[1] $mainDrive = $AvailDriveLetters[2] EndFunc ;==>_GetDriveLetters Func _GetWinNTSetupPath() $WinNTSetupPath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "WinNTSetupPath", @WorkingDir & '\') EndFunc Func _GetCachePath() $CachePath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "CachePath", @WorkingDir & '\cache') $CachePath = ($CachePath & '\') EndFunc Func _IniWriteMBR() IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "TempDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "TempDest", $bootDrive & ":") EndFunc ;==>_IniWriteMBR Func _IniWriteGPT() IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT6", "TempDest", $mainDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":") IniWrite($WinNTSetupPath & "WinNTSetup.ini", "WinNT5", "TempDest", $mainDrive & ":") EndFunc ;==>_IniWriteGPT Func _LaunchWinNTSetup() Run('cmd /c ' & '"' & $WinNTSetupPath & 'WinNTSetup_x64.exe' & '"', @WorkingDir, @SW_HIDE) EndFunc Func _Cleanup() If FileExists($CachePath) Then DirRemove($CachePath, $DIR_REMOVE) EndIf EndFunc ;==>_Cleanup Func _PrepMBR($Drive) _GetDriveLetters() _createDiskPartScriptFile($CachePath & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=MBRscrubber' & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr' & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' & @CRLF & 'Active' & @CRLF & 'Assign letter=' & $bootDrive & @CRLF & 'Exit') EndFunc ;==>_PrepMBR Func _PrepGPT($Drive) _GetDriveLetters() _createDiskPartScriptFile($CachePath & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=GPTscrubber' & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert gpt' & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'formatsystem.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par efi size=100' & @CRLF & 'format quick fs=fat32 label=System' & @CRLF & 'assign letter=' & $bootDrive & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'createmsr.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par msr size=16' & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=450' & @CRLF & 'format quick fs=ntfs label=Windows' & @CRLF & 'assign letter=' & $mainDrive & @CRLF & 'Exit') _createDiskPartScriptFile($CachePath & 'formatwinre.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=ntfs label=WinRE' & @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac' & @CRLF & 'Exit') EndFunc ;==>_PrepGPT Func _createDiskPartScriptFile($fileName, $message) $CacheFile = '' $CacheFile = FileOpen($fileName, 2) FileWrite($CacheFile, $message) FileClose($CacheFile) EndFunc ;==>_createDiskPartScriptFile Func _FormatMBR() GUISetState(@SW_HIDE) Local $aArray[6][3] = [ _ ["Cleaning Drive" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"'], _ ["Cleaning Drive" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'scrub.dat' & '"'], _ ["Cleaning Drive" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"'], _ ["Resetting Disk Attributes" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'attrib.dat' & '"'], _ ["Converting Layout to MBR" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'convert.dat' & '"'], _ ["Creating Windows Partition" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'formatmain.dat' & '"'] _ ] ProgressOn("Formatting Legacy (MBR)...", "Preparing Disk: ", "0%") For $i=0 to ubound($aArray)-1 ProgressSet($i*17 & "%", $aArray[$i][0]) ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE) Sleep(750) Next ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatMBR Func _FormatGPT() GUISetState(@SW_HIDE) Local $aArray[9][3] = [ _ ["Cleaning Drive" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"'], _ ["Cleaning Drive" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'scrub.dat' & '"'], _ ["Cleaning Drive" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'clean.dat' & '"'], _ ["Resetting Disk Attributes" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'attrib.dat' & '"'], _ ["Converting Layout to GPT" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'convert.dat' & '"'], _ ["Creating System Partition" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'formatsystem.dat' & '"'], _ ["Creating MSR Partition" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'createmsr.dat' & '"'], _ ["Creating Windows Partition" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'formatmain.dat' & '"'], _ ["Creating WinRE Partition" , 'cmd /c diskpart /s ' & '"' & $CachePath & 'formatwinre.dat' & '"'] _ ] ProgressOn("Formatting UEFI (GPT)...", "Preparing Disk: ", "0%") For $i=0 to ubound($aArray)-1 ProgressSet($i*11 & "%", $aArray[$i][0]) ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE) Sleep(750) Next ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>_FormatGPT Also it checks for an INI for the program path.. PrepareDiskNT.ini [Settings] WinNTSetupPath=(Relative-OR-FullPathToExe) No ini file But all in all converting the sections is a great way to see how this stuff works. It was already working as messy code, and I was able to understand how each section should be behaving beforehand.. Very cool... Edited December 7, 2021 by bobomb
junkew Posted December 7, 2021 Posted December 7, 2021 Code should read like a book 😉 if it doesn't most likely a few weeks later you will not understand your own code. Some minor observations (but the last script I would consider final and readable) The underscore is not needed and depends on coding style but in general I would use that more in UDF functions Prep most likely means prepare I would write that _prepareMBR (so the first time you read this you do not spend any second on interpreting what it means) _MBRPressed I probably would only put in calls to 2 functions (basically rule of thumb split GUI related functions from the actual algorithm functions) and then your 2nd functionname is only executing the algorithm so you can easily replace your gui with a different one if needed or make your tool a cmdline version of it validateGUI --> There I would validate all things user did in the GUI to be correct Instead of switch I would just use: if $areYouSure=$IDYES then <functionname> read this page https://www.autoitscript.com/autoit3/docs/functions/MsgBox.htm $IDYES (6) Earthshine 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
bobomb Posted December 13, 2021 Author Posted December 13, 2021 (edited) @benners i tried to adapt what you taught me on the ISO burning tool and integrate it here, strangely, it is working fine in Windows but when I use it in WinPE Rescue environment I get Subscript used on non-accessible variable error (It did throw an error on regular windows too but it went away? which makes this really hard to troubleshoot) it seemed to be coming from the disk list array. However the burn tool we worked on does work properly in PE, I am so I was wondering if you see anything wrong with what I did here. expandcollapse popup#NoTrayIcon #RequireAdmin #include <StringConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <ListBoxConstants.au3> #include <AutoItConstants.au3> #include <WinAPIFiles.au3> #include <Constants.au3> #include <File.au3> #include <Array.au3> #include <String.au3> Global $c_DiskList = 0 Global $MBR = 0 Global $GPT = 0 Global $bootDrive = "" Global $mainDrive = "" Cleanup() DirCreate(GetCachePath()) Opt("GUIOnEventMode", 1) MainMenu() Cleanup() Exit Func MainMenu() GUICreate('Prep/Format Disk v2.0', 300, 289) GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents") GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents") GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents") GUISetIcon(@WorkingDir & '\PrepareDiskNT.ico', 1) GUISetBkColor(0x797979) GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280) $c_DiskList = GUICtrlCreateList('', 20, 30, 260, 150, BitXOR($GUI_SS_DEFAULT_LIST, $LBS_SORT)) DiskList_Load() GUICtrlSetOnEvent(-1, "DiskList_Selected") $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25) GUICtrlSetOnEvent(-1, "RefreshPressed") GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30) $MBR = GUICtrlCreateButton('BIOS (MBR) Boot', 20, 234, 120, 40) GUICtrlSetOnEvent(-1, "MBRPressed") GUICtrlSetState(-1, $GUI_DISABLE) $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 234, 120, 40) GUICtrlSetOnEvent(-1, "GPTPressed") GUICtrlSetState(-1, $GUI_DISABLE) GUISetState() ; Just idle around While 1 Sleep(10) WEnd EndFunc ;==>MainMenu Func RefreshPressed() DiskList_Load() DiskList_Selected() EndFunc ;==>RefreshPressed Func MBRPressed() Local $s_DiskNumber = StringRegExp(GUICtrlRead($c_DiskList), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)[0] If @error Then MsgBox( _ $MB_ICONERROR, _ "Notice: ", _ "An error occured retrieving the disk number") Else If MsgBox( _ BitOR($MB_TOPMOST, $MB_ICONWARNING, $MB_YESNO, $MB_DEFBUTTON2), _ 'This will FORMAT Disk ' & $s_DiskNumber, _ 'ALL DATA WILL BE ERASED FROM DISK ' & $s_DiskNumber & @CRLF & 'Are you sure you want to proceed?') = $IDYES Then PrepMBR($s_DiskNumber) FormatMBR() IniWriteMBR() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive) LaunchWinNTSetup() Cleanup() Exit EndIf EndIf EndFunc ;==>MBRPressed Func GPTPressed() Local $s_DiskNumber = StringRegExp(GUICtrlRead($c_DiskList), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)[0] If @error Then MsgBox( _ $MB_ICONERROR, _ "Notice: ", _ "An error occured retrieving the disk number") Else If MsgBox( _ BitOR($MB_TOPMOST, $MB_ICONWARNING, $MB_YESNO, $MB_DEFBUTTON2), _ 'This will FORMAT Disk ' & $s_DiskNumber, _ 'ALL DATA WILL BE ERASED FROM DISK ' & $s_DiskNumber & @CRLF & 'Are you sure you want to proceed?') = $IDYES Then PrepGPT($s_DiskNumber) FormatGPT() IniWriteGPT() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $mainDrive) LaunchWinNTSetup() Cleanup() Exit EndIf EndIf EndFunc ;==>GPTPressed Func SpecialEvents() Select Case @GUI_CtrlId = $GUI_EVENT_CLOSE ; Code below for actions on Close Cleanup() Exit Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE ; Code below for actions on Minimize Case @GUI_CtrlId = $GUI_EVENT_RESTORE ; Code below for actions on Restore EndSelect EndFunc ;==>SpecialEvents Func Disk_GetName($i_DiskNumber) Local $s_DiskKey = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", String($i_DiskNumber)) If @error Then Return SetError(1, 0, 0) Local $s_DiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $s_DiskKey, "FriendlyName") If $s_DiskName = "" Then $s_DiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $s_DiskKey, "DeviceDesc") Return $s_DiskName EndFunc ;==>Disk_GetName Func DiskList_Load() ; load the list control with enumerated drives Local $as_Fixed = DriveGetDrive('FIXED') If IsArray($as_Fixed) Then Local $as_Removable = DriveGetDrive('REMOVABLE') ; join the two array to just make one loop through for the drives If IsArray($as_Removable) Then $as_Fixed[0] = _ArrayConcatenate($as_Fixed, $as_Removable, 1) - 1 GUICtrlSetData($c_DiskList, "") ; clear previous list info Local _ $i_DeviceNumber = 0, _ $i_LastDeviceNumber = -1 ; create a new 2D array for the device numbers Local $as_DriveInfo[$as_Fixed[0] + 1][2] = [[$as_Fixed[0], 0]] ; loop through the drive letter array, add the letter and the device number to the new array For $i = 1 To $as_Fixed[0] $as_DriveInfo[$i][0] = $as_Fixed[$i] $as_DriveInfo[$i][1] = _WinAPI_GetDriveNumber($as_Fixed[$i])[1] Next Local $ai_Columns[2] = [1, 0] ; sort the array by device number and then drive letter _ArraySort_MultiColumn($as_DriveInfo, $ai_Columns, 0, 0, 1) ;~ _ArrayDisplay($as_DriveInfo) For $i = 1 To $as_DriveInfo[0][0] ; loop through the fixed drives ; get the drive number and device name If $as_DriveInfo[$i][1] <> $i_LastDeviceNumber Then ; add the device name to the list GUICtrlSetData($c_DiskList, 'Disk ' & $as_DriveInfo[$i][1] & ' [' & Disk_GetName($as_DriveInfo[$i][1]) & ']') $i_LastDeviceNumber = $as_DriveInfo[$i][1] EndIf ; add the partition info to the list GUICtrlSetData($c_DiskList, " └ " & DriveGetLabel($as_DriveInfo[$i][0]) & " - (" & StringUpper($as_DriveInfo[$i][0]) & "\)") Next EndIf EndFunc ;==>DiskList_Load Func _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices, $oDir = 0, $iDir = 0, $iStart = 0) If Not IsArray($aIndices) Or Not IsArray($aSort) Then Return SetError(1, 0, 0) ;checks if $aIndices is an array If UBound($aSort, 2) = 0 Then Return SetError(4, 0, 0) ;array is 1D only If UBound($aIndices) > UBound($aSort, 2) Then Return SetError(2, 0, 0) ;check if $aIndices array is greater the $aSort array Local $1st, $2nd, $x, $j, $k, $l = 0 For $x = 0 To UBound($aIndices) - 1 ;check if array content makes sense If Not IsInt($aIndices[$x]) Then Return SetError(3, 0, 0) ;array content is not numeric Next $iStart = Int($iStart) < 0 ? 0 : Int($iStart) > 1 ? 1 : Int($iStart) If UBound($aIndices) = 1 Then Return _ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0]) ;check if only one index is given _ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0]) Do $1st = $aIndices[$l] $2nd = $aIndices[$l + 1] $j = 0 $k = 1 While $k < UBound($aSort) If $aSort[$j][$1st] <> $aSort[$k][$1st] Then If $k - $j > 1 Then _ArraySort($aSort, $iDir, $j, $k - 1, $2nd) $j = $k Else $j = $k EndIf EndIf $k += 1 WEnd If $k - $j > 1 Then _ArraySort($aSort, $iDir, $j, $k, $2nd) $l += 1 Until $l = UBound($aIndices) - 1 Return 1 EndFunc ;==>_ArraySort_MultiColumn Func DiskList_Selected() ; action when a list item is selected Local $i_State = $GUI_ENABLE If GUICtrlRead($c_DiskList) = '' Or StringInStr(GUICtrlRead($c_DiskList), " └ ") Then $i_State = $GUI_DISABLE GUICtrlSetState($MBR, $i_State) GUICtrlSetState($GPT, $i_State) EndFunc ;==>DiskList_Selected Func GetDriveLetters() Local $allDriveLetters = "CDEFGHIJKLMNOPQRSTUVWXYZ", $AvailDriveLetters Local $aArray = DriveGetDrive($DT_ALL) If @error Then ; An error occurred when retrieving the drives. MsgBox($MB_SYSTEMMODAL, "", "An Error Occurred! Unable to retrieve " & @CRLF & "available drive letters! Exiting Program...") Cleanup() Exit Else For $i = 1 To $aArray[0] $driveLetter = StringLeft(StringUpper($aArray[$i]), 1) $allDriveLetters = StringReplace($allDriveLetters, $driveLetter, "") Next EndIf $AvailDriveLetters = StringSplit($allDriveLetters, "") $bootDrive = $AvailDriveLetters[1] ;Get first available letter $mainDrive = $AvailDriveLetters[2] ;Get second available letter EndFunc ;==>GetDriveLetters Func GetWinNTSetupPath() Local Static $s_WinNTSetupPath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "WinNTSetupPath", @WorkingDir & '\') Return $s_WinNTSetupPath EndFunc ;==>GetWinNTSetupPath Func GetCachePath() ; get the path to the cache folder Local Static $s_CachePath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "CachePath", @WorkingDir & '\cache') & '\' Return $s_CachePath EndFunc ;==>GetCachePath Func IniWriteMBR() IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "TempDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "TempDest", $bootDrive & ":") EndFunc ;==>IniWriteMBR Func IniWriteGPT() IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "TempDest", $mainDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "TempDest", $mainDrive & ":") EndFunc ;==>IniWriteGPT Func LaunchWinNTSetup() Run('cmd /c ' & '"' & GetWinNTSetupPath() & 'WinNTSetup_x64.exe' & '"', @WorkingDir, @SW_HIDE) EndFunc ;==>LaunchWinNTSetup Func Cleanup() If FileExists(GetCachePath()) Then DirRemove(GetCachePath(), $DIR_REMOVE) EndIf EndFunc ;==>Cleanup Func PrepMBR($Drive) GetDriveLetters() createDiskPartScriptFile(GetCachePath() & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=MBRscrubber' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' & @CRLF & 'Active' & @CRLF & 'Assign letter=' & $bootDrive & @CRLF & 'Exit') EndFunc ;==>PrepMBR Func PrepGPT($Drive) GetDriveLetters() createDiskPartScriptFile(GetCachePath() & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=GPTscrubber' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert gpt' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'formatsystem.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par efi size=100' & @CRLF & 'format quick fs=fat32 label=System' & @CRLF & 'assign letter=' & $bootDrive & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'createmsr.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par msr size=16' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=450' & @CRLF & 'format quick fs=ntfs label=Windows' & @CRLF & 'assign letter=' & $mainDrive & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'formatwinre.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=ntfs label=WinRE' & @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac' & @CRLF & 'Exit') EndFunc ;==>PrepGPT Func createDiskPartScriptFile($fileName, $message) $CacheFile = '' $CacheFile = FileOpen($fileName, 2) FileWrite($CacheFile, $message) FileClose($CacheFile) EndFunc ;==>createDiskPartScriptFile Func FormatMBR() GUISetState(@SW_HIDE) Local $aArray[6][3] = [ _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrub.dat' & '"'], _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _ ["Resetting Disk Attributes", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'attrib.dat' & '"'], _ ["Converting Layout to MBR", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'convert.dat' & '"'], _ ["Creating Windows Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatmain.dat' & '"'] _ ] ProgressOn("Formatting Legacy (MBR)...", "Preparing Disk: ", "0%") For $i = 0 To UBound($aArray) - 1 ProgressSet($i * 17 & "%", $aArray[$i][0]) ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE) Sleep(750) Next ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>FormatMBR Func FormatGPT() GUISetState(@SW_HIDE) Local $aArray[9][3] = [ _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrub.dat' & '"'], _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _ ["Resetting Disk Attributes", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'attrib.dat' & '"'], _ ["Converting Layout to GPT", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'convert.dat' & '"'], _ ["Creating System Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatsystem.dat' & '"'], _ ["Creating MSR Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'createmsr.dat' & '"'], _ ["Creating Windows Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatmain.dat' & '"'], _ ["Creating WinRE Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatwinre.dat' & '"'] _ ] ProgressOn("Formatting UEFI (GPT)...", "Preparing Disk: ", "0%") For $i = 0 To UBound($aArray) - 1 ProgressSet($i * 11 & "%", $aArray[$i][0]) ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE) Sleep(750) Next ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>FormatGPT Edited December 13, 2021 by bobomb
benners Posted December 13, 2021 Posted December 13, 2021 I can't see anything obvious with the code. If you think it is the disklist then you can add msgboxes to check the values. Put them in each loop before the other code and use the title to identify which loop it is, and in the text of the message box put the loop count and total count for the array. MsgBox(0,'$as_Fixed', '$i: ' & $i & @CRLF & '$as_Fixed: ' & $as_Fixed[0]) MsgBox(0,'$as_DriveInfo', '$i: ' & $i & @CRLF & '$as_DriveInfo: ' & $as_DriveInfo[0][0]) There are basic checks to test the arrays are valid and the error points to trying to access the array element that doesn't exist. Unless you can run the script itself in PE, not the exe, then check the output window
junkew Posted December 13, 2021 Posted December 13, 2021 Add more details what fails: linenumber, error message, .... Add more msgbox/consolewrite/arraydisplay to your script to debug Be more defensive in your programming, suppose below if is false what should happen as there is no else Local $as_Fixed = DriveGetDrive('FIXED') If IsArray($as_Fixed) Then FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
bobomb Posted December 13, 2021 Author Posted December 13, 2021 (edited) @benners I put those lines in the front of the loops and got the below return.. also this is happening on the burn tool as well, they run fine on my Win11 system but its hit or miss on Win10 systems that I tested on.. same error.. It was happening on my host Win11 machine last night for a few minutes but a reboot corrected it and I thought it was a fluke.. From memory the bug that was reproduced (that i cannot reproduce now) was in this section, one of the [ ] variables... ; loop through the drive letter array, add the letter and the device number to the new array For $i = 1 To $as_Fixed[0] MsgBox(0,'$as_Fixed', '$i: ' & $i & @CRLF & '$as_Fixed: ' & $as_Fixed[0]) $as_DriveInfo[$i][0] = $as_Fixed[$i] $as_DriveInfo[$i][1] = _WinAPI_GetDriveNumber($as_Fixed[$i])[1] Next Again this isnt just inside WinPE this happened almost all machines I tested this on today.. Edited December 13, 2021 by bobomb
junkew Posted December 13, 2021 Posted December 13, 2021 Did you try to catch error state from driveGetDrive? Local $aArray = DriveGetDrive('Removable') If @error Then ; An error occurred when retrieving the drives. MsgBox($MB_SYSTEMMODAL, "", "It appears an error occurred.") Else FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets
bobomb Posted December 13, 2021 Author Posted December 13, 2021 (edited) I cannot get it to produce an error code or window in PE other than the one posted above referencing line 6732. The program must be compiled to run in PE as autoit resources are unavailable there.. As a side note I did get it to work with the original function I was using before @benners refined version... (working version posted below) expandcollapse popup#NoTrayIcon #RequireAdmin #include <StringConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <ListBoxConstants.au3> #include <AutoItConstants.au3> #include <WinAPIFiles.au3> #include <Constants.au3> #include <File.au3> #include <Array.au3> #include <String.au3> Global $c_DiskList = 0 Global $MBR = 0 Global $GPT = 0 Global $bootDrive = "" Global $mainDrive = "" Cleanup() DirCreate(GetCachePath()) Opt("GUIOnEventMode", 1) MainMenu() Cleanup() Exit Func MainMenu() GUICreate('Prep/Format Disk v2.0', 300, 289) GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents") GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents") GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents") GUISetIcon(@WorkingDir & '\PrepareDiskNT.ico', 1) GUISetBkColor(0x797979) GUICtrlCreateLabel('1: Select a disk to prepare for WinNTSetup5', 20, 10, 280) $c_DiskList = GUICtrlCreateList('', 20, 30, 260, 150, BitXOR($GUI_SS_DEFAULT_LIST, $LBS_SORT)) GUICtrlSetData(-1, GetDiskList()) GUICtrlSetOnEvent(-1, "DiskList_Selected") $Refresh = GUICtrlCreateButton('Refresh List', 110, 185, 80, 25) GUICtrlSetOnEvent(-1, "RefreshPressed") GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlCreateLabel('2: Select your desired layout...', 20, 214, 280, 30) $MBR = GUICtrlCreateButton('BIOS (MBR) Boot', 20, 234, 120, 40) GUICtrlSetOnEvent(-1, "MBRPressed") GUICtrlSetState(-1, $GUI_DISABLE) $GPT = GUICtrlCreateButton('UEFI (GPT) Boot', 160, 234, 120, 40) GUICtrlSetOnEvent(-1, "GPTPressed") GUICtrlSetState(-1, $GUI_DISABLE) GUISetState() ; Just idle around While 1 Sleep(10) WEnd EndFunc ;==>MainMenu Func RefreshPressed() GUICtrlSetData($DiskList, "") GUICtrlSetData($DiskList, GetDiskList()) DiskList_Selected() EndFunc ;==>RefreshPressed Func MBRPressed() Local $s_DiskNumber = StringRegExp(GUICtrlRead($c_DiskList), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)[0] If @error Then MsgBox( _ $MB_ICONERROR, _ "Notice: ", _ "An error occured retrieving the disk number") Else If MsgBox( _ BitOR($MB_TOPMOST, $MB_ICONWARNING, $MB_YESNO, $MB_DEFBUTTON2), _ 'This will FORMAT Disk ' & $s_DiskNumber, _ 'ALL DATA WILL BE ERASED FROM DISK ' & $s_DiskNumber & @CRLF & 'Are you sure you want to proceed?') = $IDYES Then PrepMBR($s_DiskNumber) FormatMBR() IniWriteMBR() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $bootDrive) LaunchWinNTSetup() Cleanup() Exit EndIf EndIf EndFunc ;==>MBRPressed Func GPTPressed() Local $s_DiskNumber = StringRegExp(GUICtrlRead($c_DiskList), '(?<=Disk\s)[0-9]+', $STR_REGEXPARRAYMATCH)[0] If @error Then MsgBox( _ $MB_ICONERROR, _ "Notice: ", _ "An error occured retrieving the disk number") Else If MsgBox( _ BitOR($MB_TOPMOST, $MB_ICONWARNING, $MB_YESNO, $MB_DEFBUTTON2), _ 'This will FORMAT Disk ' & $s_DiskNumber, _ 'ALL DATA WILL BE ERASED FROM DISK ' & $s_DiskNumber & @CRLF & 'Are you sure you want to proceed?') = $IDYES Then PrepGPT($s_DiskNumber) FormatGPT() IniWriteGPT() MsgBox($MB_ICONINFORMATION, "Redirecting... ", " - WinNTSetup5 will now open - " & @CRLF & @CRLF & 'Boot Drive: ' & $bootDrive & @CRLF & 'Install Drive: ' & $dataDrive) LaunchWinNTSetup() Cleanup() Exit EndIf EndIf EndFunc ;==>GPTPressed Func SpecialEvents() Select Case @GUI_CtrlId = $GUI_EVENT_CLOSE ; Code below for actions on Close Cleanup() Exit Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE ; Code below for actions on Minimize Case @GUI_CtrlId = $GUI_EVENT_RESTORE ; Code below for actions on Restore EndSelect EndFunc ;==>SpecialEvents Func Disk_GetName($i_DiskNumber) Local $s_DiskKey = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", String($i_DiskNumber)) If @error Then Return SetError(1, 0, 0) Local $s_DiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $s_DiskKey, "FriendlyName") If $s_DiskName = "" Then $s_DiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $s_DiskKey, "DeviceDesc") Return $s_DiskName EndFunc ;==>Disk_GetName Func GetDiskList() Local $aDriveInfo, $iLastDevNumber = -1 Local $aFixed = DriveGetDrive('FIXED'), $aRemovable = DriveGetDrive('REMOVABLE') Local $aDrives[ (IsArray($aFixed) ? $aFixed[0] : 0) + (IsArray($aRemovable) ? $aRemovable[0] : 0) ][3] Local $iDrive = 0 GUICtrlSetData($c_DiskList, "") ; clear previous list info For $i = 1 To UBound($aFixed) - 1 $aDrives[$iDrive][0] = $aFixed[$i] $aDriveInfo = _WinAPI_GetDriveNumber($aFixed[$i]) If Not @error Then $aDrives[$iDrive][1] = $aDriveInfo[1] $aDrives[$iDrive][2] = $aDriveInfo[2] EndIf $iDrive += 1 Next For $i = 1 To UBound($aRemovable) - 1 $aDrives[$iDrive][0] = $aRemovable[$i] $aDriveInfo = _WinAPI_GetDriveNumber($aRemovable[$i]) If Not @error Then $aDrives[$iDrive][1] = $aDriveInfo[1] $aDrives[$iDrive][2] = $aDriveInfo[2] EndIf $iDrive += 1 Next _ArraySort($aDrives, 0, 0, 0, 1) Local $aDisks[ UBound($aDrives) ] [2] Local $sOutput = "" For $i = 0 To UBound($aDrives) - 1 If IsNumber($aDrives[$i][1]) Then If $aDrives[$i][1] <> $iLastDevNumber Then $iLastDevNumber = $aDrives[$i][1] $aDisks[ $iLastDevNumber ][0] = " Disk " & $aDrives[$i][1] & " [" & Disk_GetName($aDrives[$i][1]) & "]" & "|" & @CRLF EndIf $aDisks[ $iLastDevNumber ][1] &= "; └ " & DriveGetLabel($aDrives[$i][0]) & " - " & "(" & StringUpper($aDrives[$i][0]) & "\ )" & "|" EndIf Next Redim $aDisks[$iLastDevNumber + 1][2] For $i = 0 To UBound($aDisks) - 1 $sOutput &= $aDisks[$i][0] $aSplit = StringRegExp($aDisks[$i][1], "[^;]+", 3) _ArraySort($aSplit) For $j = 0 To UBound($aSplit) - 1 $sOutput &= $aSplit[$j] Next ;$sOutput &= @CRLF Next Return $sOutput EndFunc Func DiskList_Selected() ; action when a list item is selected Local $i_State = $GUI_ENABLE If GUICtrlRead($c_DiskList) = '' Or StringInStr(GUICtrlRead($c_DiskList), " └ ") Then $i_State = $GUI_DISABLE GUICtrlSetState($MBR, $i_State) GUICtrlSetState($GPT, $i_State) EndFunc ;==>DiskList_Selected Func GetDriveLetters() Local $allDriveLetters = "CDEFGHIJKLMNOPQRSTUVWXYZ", $AvailDriveLetters Local $aArray = DriveGetDrive($DT_ALL) If @error Then ; An error occurred when retrieving the drives. MsgBox($MB_SYSTEMMODAL, "", "An Error Occurred! Unable to retrieve " & @CRLF & "available drive letters! Exiting Program...") Cleanup() Exit Else For $i = 1 To $aArray[0] $driveLetter = StringLeft(StringUpper($aArray[$i]), 1) $allDriveLetters = StringReplace($allDriveLetters, $driveLetter, "") Next EndIf $AvailDriveLetters = StringSplit($allDriveLetters, "") $bootDrive = $AvailDriveLetters[1] ;Get first available letter $mainDrive = $AvailDriveLetters[2] ;Get second available letter EndFunc ;==>GetDriveLetters Func GetWinNTSetupPath() Local Static $s_WinNTSetupPath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "WinNTSetupPath", @WorkingDir & '\') Return $s_WinNTSetupPath EndFunc ;==>GetWinNTSetupPath Func GetCachePath() ; get the path to the cache folder Local Static $s_CachePath = IniRead(@WorkingDir & '\PrepareDiskNT.ini', "Settings", "CachePath", @WorkingDir & '\cache') & '\' Return $s_CachePath EndFunc ;==>GetCachePath Func IniWriteMBR() IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "TempDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "TempDest", $bootDrive & ":") EndFunc ;==>IniWriteMBR Func IniWriteGPT() IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "BootDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT6", "TempDest", $mainDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "BootDest", $bootDrive & ":") IniWrite(GetWinNTSetupPath() & "WinNTSetup.ini", "WinNT5", "TempDest", $mainDrive & ":") EndFunc ;==>IniWriteGPT Func LaunchWinNTSetup() Run('cmd /c ' & '"' & GetWinNTSetupPath() & 'WinNTSetup_x64.exe' & '"', @WorkingDir, @SW_HIDE) EndFunc ;==>LaunchWinNTSetup Func Cleanup() If FileExists(GetCachePath()) Then DirRemove(GetCachePath(), $DIR_REMOVE) EndIf EndFunc ;==>Cleanup Func PrepMBR($Drive) GetDriveLetters() createDiskPartScriptFile(GetCachePath() & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=MBRscrubber' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert mbr' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=Windows' & @CRLF & 'Active' & @CRLF & 'Assign letter=' & $bootDrive & @CRLF & 'Exit') EndFunc ;==>PrepMBR Func PrepGPT($Drive) GetDriveLetters() createDiskPartScriptFile(GetCachePath() & 'clean.dat', 'Sel Dis ' & $Drive & @CRLF & 'clean' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'scrub.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=NTFS label=GPTscrubber' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'attrib.dat', 'Sel Dis ' & $Drive & @CRLF & 'attribute disk clear readonly' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'convert.dat', 'Sel Dis ' & $Drive & @CRLF & 'convert gpt' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'formatsystem.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par efi size=100' & @CRLF & 'format quick fs=fat32 label=System' & @CRLF & 'assign letter=' & $bootDrive & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'createmsr.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par msr size=16' & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'formatmain.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'shrink minimum=450' & @CRLF & 'format quick fs=ntfs label=Windows' & @CRLF & 'assign letter=' & $mainDrive & @CRLF & 'Exit') createDiskPartScriptFile(GetCachePath() & 'formatwinre.dat', 'Sel Dis ' & $Drive & @CRLF & 'cre par pri' & @CRLF & 'format quick fs=ntfs label=WinRE' & @CRLF & 'set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac' & @CRLF & 'Exit') EndFunc ;==>PrepGPT Func createDiskPartScriptFile($fileName, $message) $CacheFile = '' $CacheFile = FileOpen($fileName, 2) FileWrite($CacheFile, $message) FileClose($CacheFile) EndFunc ;==>createDiskPartScriptFile Func FormatMBR() GUISetState(@SW_HIDE) Local $aArray[6][3] = [ _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrub.dat' & '"'], _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _ ["Resetting Disk Attributes", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'attrib.dat' & '"'], _ ["Converting Layout to MBR", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'convert.dat' & '"'], _ ["Creating Windows Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatmain.dat' & '"'] _ ] ProgressOn("Formatting Legacy (MBR)...", "Preparing Disk: ", "0%") For $i = 0 To UBound($aArray) - 1 ProgressSet($i * 17 & "%", $aArray[$i][0]) ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE) Sleep(750) Next ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>FormatMBR Func FormatGPT() GUISetState(@SW_HIDE) Local $aArray[9][3] = [ _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'scrub.dat' & '"'], _ ["Cleaning Drive", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'clean.dat' & '"'], _ ["Resetting Disk Attributes", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'attrib.dat' & '"'], _ ["Converting Layout to GPT", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'convert.dat' & '"'], _ ["Creating System Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatsystem.dat' & '"'], _ ["Creating MSR Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'createmsr.dat' & '"'], _ ["Creating Windows Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatmain.dat' & '"'], _ ["Creating WinRE Partition", 'cmd /c diskpart /s ' & '"' & GetCachePath() & 'formatwinre.dat' & '"'] _ ] ProgressOn("Formatting UEFI (GPT)...", "Preparing Disk: ", "0%") For $i = 0 To UBound($aArray) - 1 ProgressSet($i * 11 & "%", $aArray[$i][0]) ;MsgBox($MB_ICONINFORMATION, "Troubleshooting.. ", $aArray[$i][1]) ;Troubleshoot Array Data RunWait($aArray[$i][1], @WorkingDir, @SW_HIDE) Sleep(750) Next ProgressSet(100, "Finished", "Format Completed") Sleep(1500) ProgressOff() GUISetState() EndFunc ;==>FormatGPT I guess if it works like this its ok to leave it, Benners put a bit of effort out for the other method so would have liked to use it. Its good if we cant see anything obvious that there is already a working alternative though. Edited December 13, 2021 by bobomb
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now