0
Follow
0
View

WM_DEVICECHANGE cannot capture MTP

dick0514 注册会员
2023-02-27 16:26

The MTP mode device you mentioned, that is, the Media Transfer Protocol, A protocol used to transfer files between computers and mobile devices. Unlike regular USB devices, MTP devices are not typically presented to the operating system as USB Mass Storage and therefore cannot be monitored through standard hot-swap apis.

However, if you are using a Windows operating system, you can try using the WPD API to monitor the access and unplugging of MTP devices. Specifically, you can get a list of currently connected MTP devices using the GetDevices method in the IPortableDeviceManager interface in the WPD API, And use IPortableDeviceEventSystem interface to insert and pull out events of monitoring equipment.

Here is some sample code for your reference:

Imports PortableDeviceApiLib

Public Class Form1

    Private WithEvents deviceEventSystem As New PortableDeviceManagerClass()
    Private WithEvents deviceEvents As IPortableDeviceEvents
    Private connectedDevices As New List(Of String)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' 创建 PortableDeviceManager 对象
        Dim deviceManager As New PortableDeviceManagerClass()

        ' 获取当前连接的所有设备
        Dim devices As PortableDeviceCollection = deviceManager.GetDevices()

        ' 将设备添加到列表中
        For i As Integer = 0 To devices.Count - 1
            Dim device As PortableDevice = devices(i)
            connectedDevices.Add(device.DeviceId)
            listBox1.Items.Add(device.FriendlyName)
        Next

        ' 初始化设备事件系统
        deviceEvents = DirectCast(deviceEventSystem, IPortableDeviceEvents)
        deviceEvents.AddDeviceList(Nothing)
        deviceEvents.DeviceAdded += AddressOf OnDeviceAdded
        deviceEvents.DeviceRemoved += AddressOf OnDeviceRemoved
    End Sub

    Private Sub OnDeviceAdded(ByRef pDeviceId As String) Handles deviceEvents.DeviceAdded
        ' 设备插入事件处理
        If Not connectedDevices.Contains(pDeviceId) Then
            connectedDevices.Add(pDeviceId)

            Dim device As New PortableDevice()
            device.Open(pDeviceId)

            listBox1.Items.Add(device.FriendlyName)

            device.Close()
        End If
    End Sub

    Private Sub OnDeviceRemoved(ByRef pDeviceId As String) Handles deviceEvents.DeviceRemoved
        ' 设备拔出事件处理
        If connectedDevices.Contains(pDeviceId) Then
            connectedDevices.Remove(pDeviceId)

            For Each item As Object In listBox1.Items
                If item.ToString().Contains(pDeviceId) Then
                    listBox1.Items.Remove(item)
                    Exit For
                End If
            Next
        End If
    End Sub
End Class


in the sample code above, we by PortableDeviceManagerClass GetDevices method to obtain a list of the current connection all MTP equipment, and add it to the list box. Then, we use IPortableDeviceEventSystem interface to insert and pull out event monitoring equipment, and update the equipment list box in the event handler.

sggstz 注册会员
2023-02-27 16:26

WM_DEVICECHANGE message is used to notify the application that a new device has been connected or that the state of an existing device has changed. This message can be used to monitor and react to device connections and disconnections. However, WM_DEVICECHANGE can only receive connection and disconnection information that the operating system considers to be a device, and for some devices, such as MTP devices, the operating system may not consider it a device.

In Windows, if you want to enumerate MTP Devices, you can use the Windows Portable Devices(WPD) API. The WPD API can be used to communicate with MTP devices and perform various tasks, such as browsing files, transferring files, creating folders, and so on. Here are some basic steps for the WPD API:
1. Initialize the WPD API
2. Enumerate available MTP devices
3. Open the required MTP devices
4. Perform required tasks
5. Shut down the MTP device
6. Release WPD API resources

Here is a simple example code for enumerating MTP devices:

#include 
#include <PortableDeviceApi.h>
#include <PortableDevice.h>
#include 

int main()
{
    // 初始化WPD API
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // 枚举可用的MTP设备
    HRESULT hr;
    DWORD dwCount = 0;
    LPWSTR* pnpDeviceIDs = NULL;
    hr = CoCreateInstance(CLSID_PortableDeviceManager, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pPortableDeviceManager));
    if (SUCCEEDED(hr))
    {
        hr = pPortableDeviceManager->GetDevices(NULL, &dwCount);
        if (SUCCEEDED(hr))
        {
            if (dwCount > 0)
            {
                pnpDeviceIDs = new LPWSTR[dwCount];
                hr = pPortableDeviceManager->GetDevices(pnpDeviceIDs, &dwCount);
                if (SUCCEEDED(hr))
                {
                    for (DWORD i = 0; i < dwCount; i++)
                    {
                        // 打开所需的MTP设备
                        LPWSTR pnpDeviceID = pnpDeviceIDs[i];
                        IPortableDevice* pPortableDevice = NULL;
                        hr = CoCreateInstance(CLSID_PortableDeviceFTM, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pPortableDevice));
                        if (SUCCEEDED(hr))
                        {
                            hr = pPortableDevice->Open(pnpDeviceID, NULL);
                            if (SUCCEEDED(hr))
                            {
                                // 执行所需的任务
                                // ...

                                // 关闭MTP设备
                                pPortableDevice->Close();
                            }
                            pPortableDevice->Release();
                        }
                    }
                }
            }
        }
        pPortableDeviceManager->Release();
    }

    // 释放WPD API资源
    CoUninitialize();

    return 0;
}

By using the WPD API, you can enumerate and access MTP devices in Windows.

linfeng266 注册会员
2023-02-27 16:26

Thank you for your answer, I want to ask how to capture the real-time access and removal of MTP mode device, equivalent to USB device hot plug, I checked WPDAPI, All devices need to be retrieved via GetDeives, and there doesn't seem to be any API support for hot swapping

dqxiaoying 注册会员
2023-02-27 16:26

WM_DEVICECHANGE messages can be used to capture messages about USB device insertion and removal, but the MTP device does not trigger this message when it is inserted. This is because the MTP device is not a standard USB storage device, but communicates using the USB-based MTP protocol.

If you want to enumerate MTP Devices, you can use the Windows Portable Devices(WPD) API. The WPD API provides a set of functions that you can use to detect and enumerate MTP devices connected to your computer. You can use the WPD IPortableDeviceManager in API: : GetDevices method to get connected to the computer all the MTP device on the device ID.

Here is a sample code snippet that uses the WPD API to detect and enumerate MTP devices connected to a computer:

#include <Windows.h>
#include <PortableDeviceApi.h>
#include <PortableDevice.h>
#include 

int main()
{
    HRESULT hr;
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Create the IPortableDeviceManager interface
    IPortableDeviceManager* pPortableDeviceManager;
    hr = CoCreateInstance(CLSID_PortableDeviceManager, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pPortableDeviceManager));

    // Get the list of devices
    DWORD dwNumDevices = 0;
    WCHAR** ppDevices = NULL;
    hr = pPortableDeviceManager->GetDevices(NULL, &dwNumDevices);

    if (hr == S_OK && dwNumDevices > 0)
    {
        ppDevices = new WCHAR*[dwNumDevices];
        hr = pPortableDeviceManager->GetDevices(ppDevices, &dwNumDevices);

        for (DWORD dwIndex = 0; dwIndex < dwNumDevices; dwIndex++)
        {
            // Create the IPortableDevice interface
            IPortableDevice* pPortableDevice;
            hr = CoCreateInstance(CLSID_PortableDeviceFTM, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pPortableDevice));

            // Open the device
            hr = pPortableDevice->Open(ppDevices[dwIndex], NULL);

            // Use the device

            // Close the device
            pPortableDevice->Close();
            pPortableDevice->Release();
        }
    }

    // Clean up
    if (ppDevices != NULL)
    {
        for (DWORD dwIndex = 0; dwIndex < dwNumDevices; dwIndex++)
        {
            CoTaskMemFree(ppDevices[dwIndex]);
        }
        delete[] ppDevices;
    }
    pPortableDeviceManager->Release();
    CoUninitialize();

    return 0;
}


You need to add the appropriate header files and libraries to the code, as well as initialize and release the COM libraries before connecting to the MTP device. In addition, error checking and error handling code needs to be added to handle potential errors. Hope to be accepted

coolsubo 注册会员
2023-02-27 16:26

Thank you for your answer, I want to ask how to capture the real-time access and removal of MTP mode device, equivalent to USB device hot plug, I checked WPDAPI, All devices need to be retrieved via GetDeives, and there doesn't seem to be any API support for hot swapping

About the Author

Question Info

Publish Time
2023-02-27 16:26
Update Time
2023-02-27 16:26