Detecting External SD card

Jumping off from here, I want to re-visit this.
I think this would be a good time to look at MBS for a solution (bought it a while ago but haven’t used it yet!)

For those that don’t want to look at the above link, I would like to be able to determine, cross-platform (Win/MacOS, maybe Linux later), whether an externally mounted SD card is the one I’m looking for.
On Mac it wasn’t too hard (diskutil info), using and even on Window 7 I had a WMIC call that seemed to work, but not so much on Win10! The info I need to confirm is whether a volume is:

  1. USB
  2. External
  3. Removable

So, instead of re-inventing the wheel, I wanna use my MBS stuff to try and do this. I’d also like to have automatic USB insert detection.

Having never used MBS, which USB library should I be using, or is it a different library since it’s not a HID device that I’m looking for.

@MonkeybreadSoftware ?

Since this is a “drive” I doubt the USB interface matters
The OS will mount it as a drive
I think that means you will need to add a WindProc (yeehaw !) to your app/main window that watches for the WM_DEVICE change message (which could be an add or remove of a drive)
https://docs.microsoft.com/en-us/windows/win32/devio/wm-devicechange

Thanks @npalardy .
I think I’ve fussed around with Declares enough on this particular app, so looking to see how I can do it using MBS.

Windows Functionality Suite has a pile of stuff already set up but may need updates to make it 64 bit capable
And it does have code to set up a WndProc so you can intercept Windows messages

If only we could convince Julian Samphire to contribute here once in a while - he’d be very handy since he knows windows very well

X-Plat. Norm. X-Plat.

If I only cared about Windows, I’d still be using C#. :blush:

Personally, I can’t imagine why anyone would use Xojo for Windows ONLY.

We do have WMI classes and you may need to use the InitSecurity call to make it work better since Windows 8.
We also have a lot of USB classes to find devices.

See also blog post:
Detecting drive letter for an USB Stick

Could use a little help for my first time figuring this out.

Please note that I need X-Platform, MacOS and Windows (7/8/10).

WindowsDiskChangeMBS class on Windows can listen for disk change notifications.

For macOS try NSWorkspaceDidMountNotification with NSNotificationCenterMBS and NSNotificationObserverMBS.

Once you know drive letter, you can e.g. check with WMI classes which USB device this is. On Windows GetDriveTypeMBS can tell you the drive type. For macOS DarwinMediaInfoMBS or DarwinMediaClassMBS may help.

Just NOT hook up the WindProc on macOS but would on Windows

Intercepting windows messages wont work well otherwise

What is “media”?

That doesn’t give enough info. I was using a WMIC call, but the volume # on Win10 doesn’t match the Xojo Volume Index. It seemed to on Win7 though…

IsExternalVolume(v As Integer) As FolderItem

  Dim sh As New Shell
  Dim InfoStr() As String
  Dim InfoStart, InfoEnd As Integer
  Dim InfoVal(2) As String
  Dim InfoResult(2) As String
  Dim f As FolderItem = Volume(v)

  #If TargetMacOS Then
    sh.Execute("diskutil info " + f.ShellPath)
    InfoStr = Array("Protocol:", "Device Location:", "Removable Media:")
    InfoResult = Array("USB", "External", "Removable")
  #ElseIf TargetWindows Then
    sh.Execute("wmic diskdrive where (index=" + Str(v+1) + ") get index, InterfaceType, MediaType, Model   /Format:List")
    InfoStr = Array("InterfaceType=", "MediaType=")
    InfoResult = Array("USB", "Removable Media")
  #EndIf

  If sh.ErrorCode = 0 Then
  
    System.DebugLog("Checking Volume: " + f.ShellPath)
    Dim shResult() As String = sh.Result.Split(EndOfLine)
  
    For i As Integer = 0 To shResult.UBound
    
      For j As Integer = 0 To InfoStr.UBound
        InfoStart = shResult(i).InStr(InfoStr(j))
      
        If InfoStart > 0 Then
          InfoEnd = shResult(i).InStr(InfoStart, Right(InfoStr(j), 1)) + 1
          InfoVal(j) = shResult(i).Mid(InfoEnd).Trim
          'System.DebugLog(Str(i) + ": " + InfoStr(j) + "'" + InfoVal(j) + "'")
          If InfoVal(j) <> InfoResult(j) Then Return Nil
        End If
      
      Next j
    
    Next i
  
    If InfoVal(0) = "" Then Return Nil
  Else
  
    Return Nil
  
  End If

  Return f

End Function

The various OS have different names. e.g. on macOS a disk may contain multiple Media. on Windows it may be a media containing several partitions and each has a drive letter.

Ok. Do you have a function that gives more information on Windows than GetDriveTypeMBS?
Also, any suggestions on how to get the correct index # that matches the volume? Not sure why my wmic index is different than Xojo’s volume index…

Dunno what GetDriveType returns but if it just exposes the Win32 API for GetDriveType there isnt a lot more about it to say

Those docs do point to a USB API you might check to see if its a Removable USD drive

The other API that might be of uses is GetVolumeInformation


But this doesnt really tell you about the drive type - but the kind of volume mounted at a specific path, its serial #, whether the file system on it preserves case etc etc

Probably my wmic call (above) has the most information, but unfortunately the index doesn’t match the volume # in Xojo.

Not sure how much WMI stuff you’ve done, but it’s one of the better ways to get info on Windows.

Only enough to get by :slight_smile:
If only it didnt require COM to get access to it without having to poke at a shell
I’d guess Xojo is use a different API, probably a Win32 one instead of WMI, and thats why the indexes would not match up
But thats just a guess

We have WindowsVolumeInformationMBS function in our plugin for GetVolumeInformation API.

For that we have WindowsDeviceMBS class.