3

I'm trying to get the items from within a folder on an Android phone.

However the FolderBrowserDialog won't let me select a folder from within in the phone. The path looks like this This PC\Xperia Z3 Compact\SD Card\Music

To select a folder I'm currently using:

private void button_Click(object sender, EventArgs e)
{
    System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
    if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        UserFolderLocation = dlg.SelectedPath;
    }
    else { }
}

Then when searching the folder for its contents I use:

try
{
    folderItems = Directory.GetFiles(directory).Select(f => Path.GetFileNameWithoutExtension(f)).ToArray();
}
catch (Exception e)
{
    MessageBox.Show(e.ToString());
}

If I insert the path This PC\Xperia Z3 Compact\SD Card\Music as a variable then search it, it throws a System.IO.DirectoryNotFoundException.

How do I select and use a path that doesn't begin with c:, d: etc?

guntbert
  • 536
  • 6
  • 19
difurious
  • 1,523
  • 3
  • 19
  • 32
  • Please add more info how are you running your code on Android. What frameworks are you using? etc.. – Anatolii Gabuza Oct 25 '15 at 17:04
  • This is a desktop application and the phone it is trying to connect to is running Android 5.1.1. I'm using version 4.5.2 of the .NET framework. – difurious Oct 25 '15 at 18:31

2 Answers2

4

In the end I ended up using the shell32 library. It has the ability to handle portable devices (That both include and don't include the drive letters).

Include the reference for shell32.dll and include the library:

using Shell32;

Then instead of using the FolderBrowserDialog I used the use the shell browse for folder. Which returns a strange path for a folder on a phone, for the phone I used to test the path looked like this: ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#6&fee689d&3&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SID-{20002,SECZ9519043CHOHB01,63829639168}\{013C00D0-011B-0130-3A01-380113012901}

public int Hwnd { get; private set; }

private void button3_Click(object sender, EventArgs e)
{
    Shell shell = new Shell();
    Folder folder = shell.BrowseForFolder((int)Hwnd, "Choose Folder", 0, 0);     
    if (folder == null)
    {
        // User cancelled
    }
    else
    {             
        FolderItem fi = (folder as Folder3).Self;
        UserFolderLocation = fi.Path;
    }
}

Then to select search the folder for its contents:

try
{
    Folder dir = shell.NameSpace(directory);

    List<string> list = new List<string>();
    foreach (FolderItem curr in dir.Items())
    {
        list.Add(curr.Name);
    }
    folderItems = list.ToArray();
}
catch (Exception e)
{
    MessageBox.Show(e.ToString());
}
difurious
  • 1,523
  • 3
  • 19
  • 32
  • When I try the same solution and select my phone (not a directory inside it) everything works, but when I select a folder inside my phone I get a path like this: ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\\\\?\\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#6&2a1f2d33&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\\SID-{10001,SECZ9519043CHOHB,114301988864}, but getNameSpace() just returns null. Any ideas? – Fingeg Nov 11 '21 at 04:10
0

"This PC" is only there for the eyes of the user - internally it is not used at all. You can see for yourself by applying the first marked setting in Windows Explorer screenshot

Additionally Windows assigns a drive letter to every local device - it just doesn't show it by default. (use the second marked setting to check)

So in reality you have to use (assuming you phone was assigned Drive F:) something like F:\SD Card\Music\.

Possibly related: Get List Of Connected USB Devices about the ability to find a device without knowing the assigned drive letter.

guntbert
  • 536
  • 6
  • 19