How can I Access a volume by name?

Hello,

This works on Mac…

Dim DCIM As FolderItem
Dim i as integer
Dim DCIMExists as Boolean

For i = 0 to VolumeCount-1
if Volume(i).name = “DCIM” then
DCIM = Volume(i)
DCIMExists = True
Exit
end if
next i

If not DCIMExists then
msgbox “The ““DCIM”” volume was not found.”
else
msgbox “DCIM exists”
end if

How can I modify that for PC?

Thanks.

Lennox

As you know the Name property on Windows returns the drive letter, not the “volume name” which is more properly understood on Windows as a “drive label”. This is important because the Name on the Mac is directly involved in the Path, whereas on Windows it’s pretty much for the users convenience.

The Windows Functionality Suite is your friend here, this code is from it, it’s in the FileProcessing module.

Protected Function GetVolumeName(root as FolderItem) As String
#if TargetWin32
Soft Declare Function GetVolumeInformationA Lib “Kernel32” ( root as CString, _
volName as Ptr, volNameSize as Integer, ByRef volSer as Integer, ByRef _
maxCompLength as Integer, ByRef sysFlags as Integer, sysName as Ptr, _
sysNameSize as Integer ) as Boolean
Soft Declare Function GetVolumeInformationW Lib “Kernel32” ( root as WString, _
volName as Ptr, volNameSize as Integer, ByRef volSer as Integer, ByRef _
maxCompLength as Integer, ByRef sysFlags as Integer, sysName as Ptr, _
sysNameSize as Integer ) as Boolean

dim volName as new MemoryBlock( 256 )
dim sysName as new MemoryBlock( 256 )
dim volSerial, maxCompLength, sysFlags as Integer

if System.IsFunctionAvailable( "GetVolumeInformationW", "Kernel32" ) then
  Call GetVolumeInformationW( left( root.AbsolutePath, 3 ), volName, 256, volSerial, maxCompLength, _
  sysFlags, sysName, 256 )
  
  return volName.WString( 0 )
else
  Call GetVolumeInformationA( left( root.AbsolutePath, 3 ), volName, 256, volSerial, maxCompLength, _
  sysFlags, sysName, 256 )
  
  return volName.CString( 0 )
end if

#endif
End Function

Thanks Garth,

I got that and am trying to use it.

OK, Let me explain a little more…

I have a video processor connected to a PC. That videoprocessor has a PC Card Slot with a card inserted.

What I want to do is to access images that are captured on that card.

When I connect that video processor to the PC, the drive letter may vary depending on if there are other drives connected to the PC.

So I would like to programatically identify the PC Card by name and not by letter.

How can I do that?

Thanks.

Lennox

Hi Garth,

I am using this now…

For i = 0 to VolumeCount-1
if GetVolumeName(i).name = “DCIM” then
DCIM = Volume(i)
DCIMExists = True
Exit
end if
next i

but GetVolumeName needs more parameters

What am I missing?

Thanks.

Lennox

OK Garth,

I got it now.

Thanks.

Lennox

You can also use WMI with OLEObject

Here is an example to get all volumes:

  // http://library.wmifun.net/cimv2/win32_volume.html
  
  //http://msdn.microsoft.com/en-us/library/aa394515%28v=vs.85%29.aspx
  
  Dim locator, objWMIService, objs, objProperty  As OLEOBJECT
  Dim nobjs as Integer
  
  //  Connect to WMI
  locator = new oleObject("WbemScripting.SWbemlocator", true)
  
  Dim wmiServiceParams(2) as variant
  wmiServiceParams(1) = "."
  wmiServiceParams(2) = "root\\cimv2"
  
  objWMIService= locator.invoke("ConnectServer", wmiServiceParams)
  
  // Run the WMI query
  objs = objWMIService.ExecQuery ("SELECT * FROM Win32_Volume")
  
  nobjs = objs.count - 1
  
  msgbox ("Number of Volumes: " + str(nobjs +1))
  
  For i as integer = 0 to nobjs
    Dim stringData As String
    
    objProperty = objs.ItemIndex(i)
    // ItemIndex() is not supported in Windows XP only from Windows Vista and upwards
    
    stringData = "Drive Letter: " + objProperty.Value("DriveLetter") + EndOfLine _
    + "Label: " +  objProperty.Value("Label") + EndOfLine _
    + "Description: " +  objProperty.Value("Description") + EndOfLine _
     +"Automount: "  + objProperty.Value("Automount") + EndOfLine _
    + "Block Size: " +  objProperty.Value("BlockSize") + EndOfLine _
    + "DeviceID: " + objProperty.Value("DeviceID") + EndOfLine _
    + "Capacity: " + objProperty.Value("Capacity") + EndOfLine _
    + "Caption: " + objProperty.Value("Caption") + EndOfLine _
    + "Compressed: " + objProperty.Value("Compressed") + EndOfLine _
    + "Device ID: " + objProperty.Value("DeviceID") + EndOfLine _
    + "Drive Type: " + objProperty.Value("DriveType") + EndOfLine _
    + "File System: " +  objProperty.Value("FileSystem") + EndOfLine _
    + "Free Space: " +  objProperty.Value("FreeSpace") + EndOfLine _
    + "Indexing Enabled: " +  objProperty.Value("IndexingEnabled") + EndOfLine _
    + "Maximum File Name Length: " + objProperty.Value("MaximumFileNameLength") + EndOfLine _
    + "Name: " + objProperty.Value("Name") + EndOfLine _
    + "Quotas Enabled: " + objProperty.Value("QuotasEnabled") + EndOfLine _
    + "Quotas Incomplete: " + objProperty.Value("QuotasIncomplete") + EndOfLine _
    + "Quotas Rebuilding: " + objProperty.Value("QuotasRebuilding") + EndOfLine _
    + "Serial Number: " + objProperty.Value("SerialNumber") + EndOfLine _
    + "SystemName: " + objProperty.Value("SystemName") + EndOfLine _
    + "Supports Disk Quotas: " + objProperty.Value("SupportsDiskQuotas") + EndOfLine _
    + "Supports File-Based Compression: " + objProperty.Value("SupportsFileBasedCompression") + EndOfLine
    
    msgbox stringData
  Next
  
  locator = Nil
  
exception err as oleexception
  msgbox err.message

Here is an example that display your drive letter from Volume Name:

  Sub ShowDriveLetter(VolumeName AS String)
  // http://library.wmifun.net/cimv2/win32_volume.html
  
  //http://msdn.microsoft.com/en-us/library/aa394515%28v=vs.85%29.aspx
  
  Dim locator, objWMIService, objs, objProperty  As OLEOBJECT
  Dim nobjs as Integer
  
  //  Connect to WMI
  locator = new oleObject("WbemScripting.SWbemlocator", true)
  
  Dim wmiServiceParams(2) as variant
  wmiServiceParams(1) = "."
  wmiServiceParams(2) = "root\\cimv2"
  
  objWMIService= locator.invoke("ConnectServer", wmiServiceParams)
  
  // Run the WMI query
  objs = objWMIService.ExecQuery ("SELECT * FROM Win32_Volume where Label='"+VolumeName +"'")
  
  nobjs = objs.count - 1
  
  msgbox ("Number of Volumes: " + str(nobjs +1))
  
  For i as integer = 0 to nobjs
    Dim stringData As String
    
    objProperty = objs.ItemIndex(i)
    // ItemIndex() is not supported in Windows XP only from Windows Vista and upwards
    
    stringData = "Drive Letter: " + objProperty.Value("DriveLetter") + EndOfLine _
    + "Label: " +  objProperty.Value("Label") + EndOfLine _
    + "Caption: " + objProperty.Value("Caption") + EndOfLine
    
    msgbox stringData
  Next
  
  locator = Nil
  
exception err as oleexception
  msgbox err.message
End Sub

Thanks John, quite a lot of info revealed.
Lennox

Dumb newbie question…

How do I “install” the WFS so I can use the functions. New to Xojo and haven’t worked with add-ons or plugins or whatever the WFS is…

Thanks!

WFS is a somewhat loose collection of self-contained source code snippets. You can (usually) just copy the methods/objects/modules that you need into your project. If you have the WFS project open in the Xojo IDE you can search for the GetVolumeName method and copy it from there, or you can copy lines 322-356 (inclusive) from the source file on Github

Copy that. Appreciate the quick reply!!

Still having difficulties… I had given up on it, but really need it now.

What is meant by “root as FolderItem” in Protected Function GetVolumeName(root as FolderItem) As String?

I have a SanDisk Ultra USB 3.0 USB flash drive, it is listed as “LSJ files (G)” but that G can change if another usb is inserted or if used in another computer.

How do I use "root as FolderItem? I am using Xojo 2015r4.1

Thanks.

Lennox

Try http://documentation.xojo.com/api/files/folderitem.html.DriveAt instead of root.

Thanks Emile,

I should have mentioned that I am using Xojo 2015r4.1

Thanks again.

Lennox

Here you go Lennox, I think this is what you’re looking for?

https://www.dropbox.com/s/iknztsi45xdgvew/TestVolumeEnumeration.xojo_binary_project?dl=0

Calls used FindFirstVolumeW, FindNextVolumeW, FindVolumeClose, GetVolumePathNamesForVolumeNameW, GetVolumeInformationW (added here for to aid future searches)

Hi Julian,

Thanks, I am using Xojo 2015r4.1, maybe it is too old for this.
I ran and also compiled it without any errors.
What I got is a window named Untitled with two menus… File and Edit.
File has a menuitem named Exit.
The window itself is blank.

I will download a newer version and see if there is a difference.

Thanks again.

Lennox

@Lennox Jacob :
add a textarea to the window
change the code in the open event to:

[code]Dim paths() As String = GetPathByVolumeName("")

For Each path As String In paths()
system.DebugLog(“path=” + path)
TextArea1.AppendText “path=” + path + EndOfLine
Next[/code]

IMHO you should see some more in the window.

Personally i find it easier to show test data in a textarea instead of the systemlog as Julian does, but that’s just me…! But as you can see Julian is the brilliant genius!

http://documentation.xojo.com/api/deprecated/volume.html

Emile, thanks for the suggestion, but you can’t easily get the volume name using that, so you’d still need to dip into Declares.

Lennox, if you run the program, then click this tab at the bottom of the IDE window, you’ll see the output:

This is the Messages Panel, it can be used for debugging and outputting information at runtime, it’s very handy for simple things like this https://documentation.xojo.com/getting_started/using_the_ide/find-_errors-_messages_panels.html#Messages

Hi Julian,

my answer comes from:

A second read leads to understand Lennox already knows about Volume (earlier in the thread, in 2015).

OK Thanks.

Julian, thanks for that , I did not know about that, but all it gives is this…
my Application.exe launched
path=H:\

Andre, I got this…
https://ibb.co/1n2wzGr

Emile, I did not get it to work, I gave up.

Thanks again.

Lennox