USBハードドライブとSSDをmacOSのUSBキー/ペンドライブと区別する方法

Dec 11 2020

コードで、外付けUSBハードドライブとソリッドステートドライブを一方でUSBスティックと区別することはどのように可能ですか?

私はmacOSAPI(またはシステムコール、割り込み、メッセージングなど)に精通していませんが、I / Oキットまたはディスクアービトレーションに含まれていると思いますか?

ターミナルコマンドラインsystem_profiler SPUSBDataTypeで、「リムーバブルメディア」の下にリストされているこの情報を使用および表示できます。

回答

2 vadian Dec 15 2020 at 15:19

リムーバブル/イジェクト可能な情報はURLから直接取得できます。区別するにはイジェクト可能で十分です。

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

私はこれまでmacOSやSwiftのコードを書いたことがありません。この概念実証をまとめるのに十分なことを学びました。それは私の質問のように双方向の一般化をするだけです:取り外し可能および/または排出可能なメディアと取り外し不可能な非排出可能なメディア。DMGはUSBスティックとSDカードにまとめられています。光学ディスクやフロッピーディスクも確かにそうです。「リムーバブル」と「イジェクト可能」のどちらか一方だけが当てはまるストレージタイプのようなものがあるかどうかはわかりませんが、両方は当てはまりません...

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