问题
How is it possible for code to distinguish between external USB hard drives and solid-state drives on the one hand versus USB sticks on the other hand?
I'm not familiar with macOS APIs (or system calls, interrupts, messaging, and other things) but I'm guessing it would be in I/O Kit or Disk Arbitration?
On the Terminal command line you can use system_profiler SPUSBDataType
and see this information listed under "Removable Media".
回答1:
You can get the removable/ejectable information directly from the URL, ejectable is sufficient for the differentiation
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)
}
回答2:
I've never written macOS or Swift code before. I learned just enough to get this proof of concept together. It only makes the two-way generalization as in my question: Removable and/or ejectable media vs non-removable non-ejectable media. DMGs are lumped with USB sticks and SD cards. Optical and floppy disks surely are too. I have no idea if there's such thing as a storage type where only one of "removable" and "ejectable" is true but not both...
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")
}
}
}
来源:https://stackoverflow.com/questions/65245018/how-to-distinguish-usb-hard-drives-and-ssds-from-usb-keys-pen-drives-on-macos