bobomb Posted December 4, 2021 Share Posted December 4, 2021 (edited) I am using the below function in a script I posted in its entirety here earlier. This gets 2 available drive letters and assigns them to variables. Func _GetDriveLetters() $driveletter = StringSplit("C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z",",",1) For $i = 1 to $driveletter[0] step +1 $var = DriveStatus( $driveletter[$i] & ":" ) If $var = "INVALID" Then $bootDrive=($driveletter[$i]) For $i = 1 to $driveletter[0] step +1 $var = DriveStatus( $driveletter[$i] & ":" ) If $var = "INVALID" Then $mainDrive=($driveletter[$i]) EndIf Next EndIf Next EndFunc ;==>_GetDriveLetters This actually works but I believe it is luck. I merely added a second "for" command inside of the first, the first one($bootDrive) pulls from the left of the stringsplit and the second one pulls from the right side of the stringsplit. e.g. if available it will default to C and Z. Is there a better way to do this? I am obviously not instructing it to pull from different ends of the string it just happens to do so, is there an explanation for this? It's the only reason it is working as far as I can tell otherwise it would likely pick the same letter for both variables. Is this something that is best left as is? Edited December 4, 2021 by bobomb Link to comment Share on other sites More sharing options...
Musashi Posted December 4, 2021 Share Posted December 4, 2021 (edited) Try : (from @Danny35d : how-to-list-available-drive-letters ) #include <Array.au3> $FreeDriveList = _GetFreeDriveLetters() _ArrayDisplay($FreeDriveList) Func _GetFreeDriveLetters() Dim $aArray[1] For $x = 67 To 90 If DriveStatus(Chr($x) & ':\') = 'INVALID' Then ReDim $aArray[UBound($aArray) + 1] $aArray[UBound($aArray) - 1] = Chr($x) & ':' EndIf Next $aArray[0] = UBound($aArray) - 1 Return($aArray) EndFunc EDIT : @bobomb For an array containing the enumerated drives see : DriveGetDrive Edited December 4, 2021 by Musashi enhanced "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." Link to comment Share on other sites More sharing options...
bobomb Posted December 4, 2021 Author Share Posted December 4, 2021 (edited) Thank you for your speedy response! While the method you posted would allow for more granular control over all available drive letters from within the created array The method I posted is already efficient at retrieving the drive letters, I think a better way to ask, is maybe... is there a way get the same result (2 available drive letters) with a single for command with the method I am currently using? i am following the logic and other than the double for command and the pulling from both sides of the string i am mostly worried about stepping on drive letters when getting the second one Or would this logic be safer to not accidentally pick the same drive letter for the 2 variables? Func _GetDriveLetters() $driveletter = StringSplit("C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z",",",1) For $i = 1 to $driveletter[0] step +1 $var = DriveStatus( $driveletter[$i] & ":" ) If $var = "INVALID" Then $bootDrive=($driveletter[$i]) For $i = 1 to $driveletter[0] step +1 ; Something like this that works lol If $bootDrive=($driveletter[$i]) Then $i = (1 to $driveletter[0] step +1) EndIf ; end example $var = DriveStatus( $driveletter[$i] & ":" ) If $var = "INVALID" Then $mainDrive=($driveletter[$i]) EndIf Next EndIf Next EndFunc ;==>_GetDriveLetters Edited December 4, 2021 by bobomb Link to comment Share on other sites More sharing options...
bobomb Posted December 4, 2021 Author Share Posted December 4, 2021 (edited) I guess I could do this and leave an empty if/then/else command while checking against the first variable to keep the loop going if they are the same, it already moves to the next delimited char (although from the other end?) when the first variable is assigned.. But this appears to check to make sure I am not picking the same letter twice in the event there is only 1 letter available.. Func _GetDriveLetters() $driveletter = StringSplit("C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z",",",1) For $i = 1 to $driveletter[0] step +1 $var = DriveStatus( $driveletter[$i] & ":" ) If $var = "INVALID" Then $bootDrive=($driveletter[$i]) For $i = 1 to $driveletter[0] step +1 $var = DriveStatus( $driveletter[$i] & ":" ) If $bootDrive=($driveletter[$i]) Then Else If $var = "INVALID" Then $mainDrive=($driveletter[$i]) EndIf EndIf Next EndIf Next EndFunc ;==>_GetDriveLetters I am very unsure if I am butchering this right now.. Is this bad form/technique? I feel like this is assigning the entire stringsplit before exiting the loop Edited December 4, 2021 by bobomb Link to comment Share on other sites More sharing options...
bobomb Posted December 4, 2021 Author Share Posted December 4, 2021 (edited) Ok this actually works perfectly getting the next 2 available drive letters without stepping on itself. Unless I'm doing something that is a nono here I guess I will settle with this. After looking at For...To...Step...Next in help section I saw the steps being used are being counted and I was using the same variable for both loops.. Func _GetDriveLetters() $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 $i = 1 to $driveletter[0] step +1 $var = DriveStatus($driveletter[$i] & ":") If $var = "INVALID" Then $bootDrive=($driveletter[$i]) For $x = 1 to $driveletter[0] step +1 $var = DriveStatus($driveletter[$x] & ":") If $bootDrive=($driveletter[$x]) Then Else If $var = "INVALID" Then $mainDrive=($driveletter[$x]) EndIf EndIf Next EndIf Next EndFunc ;==>_GetDriveLetters .. I know when I learn more I will cringe at these questions I've asked.. Edited December 4, 2021 by bobomb Link to comment Share on other sites More sharing options...
bobomb Posted December 4, 2021 Author Share Posted December 4, 2021 (edited) By the way credit for the original method is from the below post(NeoFox), almost forgot to add that: https://www.autoitscript.com/forum/profile/16583-neofox/ Edited December 4, 2021 by bobomb Link to comment Share on other sites More sharing options...
Solution Musashi Posted December 4, 2021 Solution Share Posted December 4, 2021 (edited) 1 hour ago, bobomb said: and leave an empty if/then/else command Why : [...] If $bootDrive=($driveletter[$x]) Then Else If $var = "INVALID" Then $mainDrive=($driveletter[$x]) EndIf EndIf [...] instead of : [...] If Not ($bootDrive=($driveletter[$x])) Then If $var = "INVALID" Then $mainDrive=($driveletter[$x]) EndIf EndIf [...] BTW : A small but runnable reproducer script would be helpful to see, e.g. which variables are declared Global . Edited December 4, 2021 by Musashi typo bobomb 1 "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." Link to comment Share on other sites More sharing options...
bobomb Posted December 4, 2021 Author Share Posted December 4, 2021 I am not making this for myself this is for anyone who wants to use modify whatever... source is listed in another post here I wasnt trying to crosspost but here is the link for the entire thing (already updated): Musashi 1 Link to comment Share on other sites More sharing options...
Musashi Posted December 4, 2021 Share Posted December 4, 2021 7 minutes ago, bobomb said: ... source is listed in another post Ah, Ok, I hadn't looked into that thread. "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." Link to comment Share on other sites More sharing options...
junkew Posted December 6, 2021 Share Posted December 6, 2021 I am not sure what you are exactly trying to find out for the different drives are you saying: If I have drives a,b,c,d then i want to have [e-z] returned as beeing free drive letters to use? and as such e and z you want to have returned I probably would start with https://www.autoitscript.com/autoit3/docs/functions/DriveGetDrive.htm #include <AutoItConstants.au3> #include <MsgBoxConstants.au3> local $allDriveLetters="CDEFGHIJKLMNOPQRSTUVWXXYZ" Local $aArray = DriveGetDrive($DT_ALL) If @error Then ; An error occurred when retrieving the drives. MsgBox($MB_SYSTEMMODAL, "", "It appears an error occurred.") Else For $i = 1 To $aArray[0] ; Show all the drives found and convert the drive letter to uppercase. ;MsgBox($MB_SYSTEMMODAL, "", "Drive " & $i & "/" & $aArray[0] & ":" & @CRLF & StringUpper($aArray[$i])) $driveLetter=stringleft(StringUpper($aArray[$i]),1) $allDriveLetters=stringreplace($allDriveLetters,$driveLetter,"") Next EndIf consolewrite("Drive letters available :" & @CRLF & $allDriveLetters & @CRLF) consolewrite("First: " & stringleft($allDriveLetters,1) & @CRLF) consolewrite("Last: " & stringright($allDriveLetters,1) & @CRLF) and with wmi you can query info $oWMISvc = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2") $colDiskDrives = $oWMISvc.ExecQuery("SELECT * FROM Win32_DiskDrive") For $oDiskDrive In $colDiskDrives ConsoleWrite("DiskDrive = " & $oDiskDrive.DeviceId & " Caption = " & $oDiskDrive.Caption & @LF) $sQuery = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" & $oDiskDrive.DeviceId & "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition" $colPartitions = $oWMISvc.ExecQuery($sQuery) For $oPartition In $colPartitions ConsoleWrite(@TAB & "Partition = " & $oPartition.DeviceId & @LF) $sQuery = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & $oPartition.DeviceId & "'} WHERE AssocClass = Win32_LogicalDiskToPartition" $colLogicalDisks = $oWMISvc.ExecQuery($sQuery) For $oLogicalDisk In $colLogicalDisks ConsoleWrite(@TAB & @TAB & "LogicalDisk = " & $oLogicalDisk.DeviceId & @LF) Next Next Next bobomb 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
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