Comment distinguer les disques durs USB et les SSD des clés USB / clés USB sur macOS

Dec 11 2020

Comment le code peut-il faire la distinction entre les disques durs USB externes et les disques SSD d'une part et les clés USB d'autre part?

Je ne suis pas familier avec les API macOS (ou les appels système, les interruptions, la messagerie et d'autres choses) mais je suppose que ce serait dans le kit d'E / S ou l'arbitrage de disque?

Sur la ligne de commande du terminal, vous pouvez utiliser system_profiler SPUSBDataTypeet voir ces informations répertoriées sous «Média amovible».

Réponses

2 vadian Dec 15 2020 at 15:19

Vous pouvez obtenir les informations amovibles / éjectables directement à partir de l'URL, l'éjectable suffit pour la différenciation

let mountedVolumeURLs = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: [.nameKey, .volumeIsEjectableKey])!
for volumeURL in mountedVolumeURLs where volumeURL.path == "/" || volumeURL.path.hasPrefix("/Volumes") {
    let resources = try! volumeURL.resourceValues(forKeys: [.nameKey, .volumeIsEjectableKey])
    
    let ejectable = resources.volumeIsEjectable!
    let name = resources.name!
    
    var type = name + " is "
    type += ejectable ? "USB stick, SD card, etc" : "hard drive, SSD, etc";
    type += " ("
    type += ejectable ? "" : "not "
    type += "ejectable)"
    print(" ", type)
}
1 hippietrail Dec 14 2020 at 19:19

Je n'ai jamais écrit de code macOS ou Swift auparavant. J'ai appris juste assez pour rassembler cette preuve de concept. Cela ne fait que la généralisation bidirectionnelle comme dans ma question: média amovible et / ou éjectable vs média non amovible non éjectable. Les DMG sont regroupés avec des clés USB et des cartes SD. Les disques optiques et les disquettes le sont sûrement aussi. Je n'ai aucune idée s'il existe un type de stockage où un seul des termes "amovible" et "éjectable" est vrai mais pas les deux ...

import Cocoa
import DiskArbitration

if let session = DASessionCreate(kCFAllocatorDefault) {
    let mountedVolumeURLs = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: nil)!
    for volumeURL in mountedVolumeURLs {
        if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volumeURL as CFURL),
            let bsdName = DADiskGetBSDName(disk) {
            let bsdString = String(cString : bsdName)
            print(volumeURL.path, bsdString)
            
            if let descDict = DADiskCopyDescription(disk) as? [String: CFTypeRef] {
                let removable : Bool, ejectable : Bool
                if let val = descDict["DAMediaRemovable"] as? Bool {
                    removable = val
                    if let val = descDict["DAMediaEjectable"] as? Bool {
                        ejectable = val

                        var type = ""
                        
                        type += removable || ejectable ? "USB stick, SD card, etc" : "hard drive, SSD, etc";
                        
                        type += " ("
                        
                        type += removable ? "" : "not "
                        type += "removable"
                        type += ", "
                        type += ejectable ? "" : "not "
                        type += "ejectable"
                        
                        type += ")"

                        print(" ", type)
                    }
                }
            }
            print("\n")
        }
    }
}