11

When I connect my Android phone to my Windows 7 with USB cable, Windows pop-up a window and show me the phone's internal storage at Computer\HTC VLE_U\Internal storage from Windows Explorer. But there is no drive letter linked with this phone storage! Inside Windows Explorer, I can manipulate the file system.

How can I manipulate the same files or folders from C# program?

As I tested,

DirectoryInfo di = new DirectoryInfo(@"C:\"); 

works, but

DirectoryInfo di = new DirectoryInfo(@"Computer\HTC VLE_U\Internal storage");

failed.

But in Windows Explorer, IT IS Computer\HTC VLE_U\Internal storage! No drive letter!

Yes, this is MTP device.

I see this answer in Stack Overflow, but the return results are empty for me after running this code

var drives = DriveInfo.GetDrives();
var removableFatDrives = drives.Where(
    c=>c.DriveType == DriveType.Removable &&
    c.DriveFormat == "FAT" && 
    c.IsReady);
var androids = from c in removableFatDrives
    from d in c.RootDirectory.EnumerateDirectories()
    where d.Name.Contains("android")
    select c;

I get correct drives. But android phone's internal storage is not here. Both removableFatDrives and androids are empty for me.

Community
  • 1
  • 1
Herbert Yu
  • 549
  • 5
  • 13
  • MTP is not mounted as a file system and cannot be accessed using those APIs. – SLaks Jul 30 '14 at 00:01
  • @SLaks Is there a way to assign a drive letter to MTP device? Or alternatively: How can I access this MTP device, Any API here? Thanks in advance – Herbert Yu Aug 01 '14 at 06:18
  • Found this URL: https://bitbucket.org/derekwilson/podcastutilities/src/b18a9926c1dcbfb884b34b9865ebaec96abfdb82/PodcastUtilities.PortableDevices/?at=default . And I'll try to use these source codes, to see if I can connect to this phone. – Herbert Yu Aug 01 '14 at 06:23
  • @Herbert did you find a solution to your problem? I am looking for a solution too, if you have, please post it here and mark it as a solution. – IdontCareAboutReputationPoints Jul 29 '15 at 17:03
  • @MusuNaji No, unfortunately. But I found, I can use Windows Explorer to access it even there is no drive letter assigned to my phone. Strange, but worked. – Herbert Yu Aug 11 '15 at 18:37
  • @HerbertYu what is windows explorer? you included a com object that is a browser? – Yogurtu May 31 '18 at 20:26

2 Answers2

7

I used nugetpackage "Media Devices by Ralf Beckers v1.8.0" This made it easy for me to copy my photos from my device to my computer and vice versa.

 public class Program
{
    static void Main(string[] args)
    {
        var devices = MediaDevice.GetDevices();
        using (var device = devices.First(d => d.FriendlyName == "Galaxy Note8"))
        {
            device.Connect();
            var photoDir = device.GetDirectoryInfo(@"\Phone\DCIM\Camera");

            var files = photoDir.EnumerateFiles("*.*", SearchOption.AllDirectories);

            foreach (var file in files)
            {
                MemoryStream memoryStream = new System.IO.MemoryStream();
                device.DownloadFile(file.FullName, memoryStream);
                memoryStream.Position = 0;
                WriteSreamToDisk($@"D:\PHOTOS\{file.Name}", memoryStream);
            }
            device.Disconnect();
        }

    }

    static void WriteSreamToDisk(string filePath, MemoryStream memoryStream)
    {
        using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
        {
            byte[] bytes = new byte[memoryStream.Length];
            memoryStream.Read(bytes, 0, (int)memoryStream.Length);
            file.Write(bytes, 0, bytes.Length);
            memoryStream.Close();
        }
    }
}
ZackOfAllTrades
  • 479
  • 5
  • 11
2

This question definitely help me! I was trying to write a simple program to auto sync my photos/videos from an android device to my computer. Hence I ended up asking the same question as Herbert Yu, how do I access the device path when there are no drive letters?

ZackOfAllTrades' answer helped me. Thumbs up!

I copied ZackOfAllTrades' code, tweaked it to my needs and Bang! it worked, but not for long. I have a 108MP camera on my Xiaomi Note 10 Pro, 4 minutes videos can easily go past 1GB; some of my videos are 4GBs large. using ZackOfAllTrades' code, I quickly ran into OutOfMemoryException when invoking MediaDevice.DownloadFile(string, Stream).

[1] My initial attempt at fixing this is to go to project properties, set my project to build for x64, that seems to get rid of OutOfMemoryException; I am able to start copying files between 1GB to 2GB without any problems.

[2] However, as soon as I start copying files of 2.5GB large, the WriteStreamToDisk() util function written by ZackOfAllTrades started to complain about Stream too long.

Then I realized that DownloadFile takes a Stream object, it doesn't need to be a MemoryStream as Zack has used. So I switched it to a FileStream object as follow

static void Main(string[] args)
{
    string DeviceNameAsSeenInMyComputer = "Mi Note 10 Pro";

    var devices = MediaDevice.GetDevices();

    using (var device = devices.Where(d => d.FriendlyName == DeviceNameAsSeenInMyComputer || d.Description == DeviceNameAsSeenInMyComputer).First())
    {
        device.Connect();
        var photoDir = device.GetDirectoryInfo(@"\Internal shared storage\DCIM\Camera");
        var files = photoDir.EnumerateFiles("*.*", SearchOption.TopDirectoryOnly);

        foreach (var file in files)
        {
            string destinationFileName = $@"F:\Photo\{file.Name}";
            if (!File.Exists(destinationFileName))
            {
                using (FileStream fs = new FileStream(destinationFileName, FileMode.Create, System.IO.FileAccess.Write))
                {
                    device.DownloadFile(file.FullName, fs);
                }
            }

            
        }
        device.Disconnect();
    }

    Console.WriteLine("Done...");
    Console.ReadLine();
}

Worked beautifully. When I am using ZackOfAllTrades' code, VS profiler shows memory consumption at about 2.5 times the size of file. Eg: if the file is 1.5GB large, the memory consumption is roughly 4GB.

But if one is to copy to file system directly, the memory consumption is negligible (<50mb)

The other issues is with MediaDevice.FriendlyName. In ZackOfAllTrades' example, he is using a Samsung, and I am guessing Samsung phones supported this property. I did not bother digging out my old Samsung to try this out. I know for sure my Xiaomi Note 10 Pro did not support FriendlyName, instead what worked for me is MediaDevice.Description

Hope this helps others who are asking the same question.

Ji_in_coding
  • 1,601
  • 1
  • 12
  • 17