Unterscheiden von USB-Festplatten und SSDs von USB-Sticks / USB-Sticks unter macOS

Dec 11 2020

Wie kann Code zwischen externen USB-Festplatten und Solid-State-Laufwerken einerseits und USB-Sticks andererseits unterscheiden?

Ich bin nicht mit MacOS-APIs (oder Systemaufrufen, Interrupts, Messaging und anderen Dingen) vertraut, aber ich vermute, dass dies in I / O Kit oder Disk Arbitration der Fall ist.

In der Terminal-Befehlszeile können system_profiler SPUSBDataTypeSie diese Informationen unter "Wechselmedien" verwenden und anzeigen.

Antworten

2 vadian Dec 15 2020 at 15:19

Sie können die entfernbaren / auswerfbaren Informationen direkt von der URL abrufen. Auswerfbar ist für die Unterscheidung ausreichend

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

Ich habe noch nie MacOS- oder Swift-Code geschrieben. Ich habe gerade genug gelernt, um diesen Proof of Concept zusammenzubringen. Es erfolgt nur die bidirektionale Verallgemeinerung wie in meiner Frage: Wechselmedien und / oder auswerfbare Medien im Vergleich zu nicht entfernbaren nicht auswerfbaren Medien. DMGs werden mit USB-Sticks und SD-Karten zusammengefasst. Optische und Disketten sind es sicherlich auch. Ich habe keine Ahnung, ob es einen Speichertyp gibt, bei dem nur einer von "entfernbar" und "auswerfbar" wahr ist, aber nicht beide ...

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")
        }
    }
}