androidvb.netwpd

WPD/MTP PortableDevices, Content is always empty (Windows, VisualStudio 2012, VB.NET)


Problem is tested with NuGet package PortableDevices and the solution from here: Accessing an MTP device in Visual Basic .NET

I want to get a file list from a Samsung Android Tablet. I can connect, but GetContents() returns no files (root.Files.Count = 0). Thanks in advance.

Dim Devices As New PortableDeviceCollection()
Devices.Refresh()
Dim tablet As PortableDevice
tablet = Devices.First()
tablet.Connect()
Dim root = tablet.GetContents()

Solution

  • For me, the problem is solved. First, let me explain the effect: in the list of portable devices in my windows 10 device manager are 4 devices from a Card Reader and the Samsung tablet inserted in position 2. The Interop.PortableDeviceApiLib.dll had the problem to retrieve more the one device describted here: Enumerating Windows Portable Devices in C# With this issue, the GetDevices() returns ever only one device, in my case the last device from Card Reader with no files. When connecting one more device (another smartphone), it becomes the last device and the code (Windows Portable Devices.zip from Accessing an MTP device in Visual Basic .NET) works fine.

    The solution: I fix the marshalling problem in the interop assembly as explained in the accepted answer (Enumerating Windows Portable Devices in C#) and copy the new Interop dll over all existing Interop.PortableDeviceApiLib.dll (set Embed Interop Types to False in Refs). The code in PortableDeviceCollection.cs (zip package from here: Accessing an MTP device in Visual Basic .NET) i have changed as as follow:

    public void Refresh()
    {
        this._deviceManager.RefreshDeviceList();
    
        // Determine how many WPD devices are connected
        // new, according to https://learn.microsoft.com/en-us/windows/win32/wpd_sdk/enumerating-devices
        uint count = 1;
        string[] s = null;
        this._deviceManager.GetDevices(s, ref count);
    
    
        // Retrieve the device id for each connected device
        var deviceIds = new string[count];
        // old: this._deviceManager.GetDevices(ref deviceIds[0], ref count);
        this._deviceManager.GetDevices(deviceIds, ref count);
        foreach(var deviceId in deviceIds)
        {
            Add(new PortableDevice(deviceId));
        }
    }
    

    Unfortunately, the Interop.PortableDeviceApiLib.dlls must replaced with the new created dll after each Clean in Visual Studio. Edit: In the article from Andrew Trevarrow, Fun with MTP in C# (http://andrewt.com/2013/06/15/fun-with-mtp-in-c.html), is a hint to prevent this problem: when all done, remove the referenece to PortableDeviceApiLib Type Library from C# project "PortableDevices" and add a reference to the new Interop.PortableDeviceApiLib.dll (in separate folder) and change "Embed Interop Types" for the dll to False.