【问题标题】:How to get MTP device Available Storage & Storage Capacity using C#?如何使用 C# 获取 MTP 设备可用存储和存储容量?
【发布时间】:2017-04-07 08:01:15
【问题描述】:

我正在使用 PortableDevice API 来获取 MTP 设备检测和设备属性。 我想获取 MTP 设备存储,例如存储容量和可用存储。这是我获取设备友好名称的示例代码,

public string FriendlyName
    {
        get
        {
            if (!this._isConnected)
            {
                throw new InvalidOperationException("Not connected to device.");
            }

            // Retrieve the properties of the device
            IPortableDeviceContent content;
            IPortableDeviceProperties properties;
            this._device.Content(out content);
            content.Properties(out properties);

            // Retrieve the values for the properties
            IPortableDeviceValues propertyValues;
            properties.GetValues("DEVICE", null, out propertyValues);

            // Identify the property to retrieve
            var property = new _tagpropertykey();
            property.fmtid = new Guid(0x26D4979A, 0xE643, 0x4626, 0x9E, 0x2B,
                                      0x73, 0x6D, 0xC0, 0xC9, 0x2F, 0xDC);
            property.pid = 12;

            // Retrieve the friendly name
            string propertyValue;
            propertyValues.GetStringValue(ref property, out propertyValue);

            return propertyValue;
        }
    }

我想以同样的方式从 MTP 设备读取设备存储和可用空间。

我试过这样,但我错过了一些东西,

IPortableDeviceKeyCollection keys;
        properties.GetSupportedProperties(objectId, out keys);

        IPortableDeviceValues values;
        properties.GetValues(objectId, keys, out values);

        // Get the name of the object
        string name;
        var property = new _tagpropertykey();            
        property.fmtid = new Guid(0x01A3057A, 0x74D6, 0x4E80, 0xBE, 0xA7, 0xDC, 0x4C, 0x21, 0x2C, 0xE5, 0x0A);
        property.pid = 7;
        values.GetStringValue(property, out name);

        // Get the type of the object
        Guid contentType;
        property = new _tagpropertykey();

        property.fmtid = new Guid(0x01A3057A, 0x74D6, 0x4E80, 0xBE, 0xA7, 0xDC, 0x4C, 0x21, 0x2C, 0xE5, 0x0A);

        property.pid = 5;
        values.GetGuidValue(property, out contentType);

        var storageType = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);

        var functionalType = new Guid(0x8F052D93, 0xABCA, 0x4FC5, 0xA5, 0xAC, 0xB0, 0x1D, 0xF4, 0xDB, 0xE5, 0x98);

....................... ....................................

提前致谢。

【问题讨论】:

    标签: c# mtp wpd


    【解决方案1】:
    //Collecting the supported keys
    IPortableDeviceKeyCollection keys;
    properties.GetSupportedProperties(objectId, out keys);
    
    //Init
    _tagpropertykey key = new _tagpropertykey();
    uint count = 0;
    keys.GetCount(ref count);
    
    //temporarily store each key and display
    for (uint i = 0; i < count; i++)
    {
        keys.GetAt(i, ref key);
        Console.WriteLine("fmtid " + key.fmtid + " pid " + key.pid);
    }
    

    仅供参考,这是一些显示支持的属性键的代码。如果您传递的 objectID 不是根文件夹,而是第一个文件夹(在资源管理器中,例如 Internal Storage),您将看到

    WPD_STORAGE_CAPACITY _tagpropertykey
    

    我强烈建议创建一个类来存储所有 PropertyKeys¹,这样看起来会更好看。

    我认为您可能应该看一下 cgeers 教程,所以我会以此为基础。

    1. 为您的PortableDevice 类添加一个根文件夹以便于访问:

      private readonly PortableDeviceFolder root = new PortableDeviceFolder("DEVICE", "DEVICE");
      public PortableDeviceFolder Root
      {
          get
          {
              return root;
          }
      }
      
    2. 为您的文件夹 objectId 使用该代码(如前所述,例如内部存储)

      IPortableDeviceProperties properties;
      content.Properties(out properties);
      
      IPortableDeviceValues values;
      properties.GetValues(objectId, keys, out values);
      
      //capacity stored as UI8 in PropVariant as stated in ² -> ulong
      ulong capacity = 0;
      values.GetUnsignedLargeIntegerValue(WPD_STORAGE_CAPACITY_IN_OBJECTS, out capacity); 
      

    此代码与 cgeers 中的 Refresh 方法(和子方法)的一部分非常相似,因此您的文件夹对象已经被创建。

    您可以从该文件夹中检索此信息这一事实要么是纯知识/常识(Win Explorer 还显示该文件夹的信息),要么可以通过执行顶部的第一行代码来了解。

    我 - 为我自己 - 更改了 PortableDeviceFolder 结构,该结构现在包含一个位于文件夹中的 PortableDeviceObjects 集合,每个集合还保存其父级。
    像这样访问文件夹非常容易,例如要获得您想要的folderId,我只需使用以下代码:

    PortableDeviceCollection c = new PortableDeviceCollection();
    c.Refresh();
    PortableDevice device = c.First();
    device.Root.RefreshFiles();
    PortableDeviceFolder internalstorageFolder = (PortableDeviceFolder)device.Root.Files.First();
    

    您可以尝试自己实现这样的结构,也可以完全采用其他方式,我认为没有完美的访问结构,因此需要找出最适合的结构。

    ¹:https://github.com/gtaglang/WpdLib/blob/master/src/WpdLib/WpdProperties.cs

    ²:https://msdn.microsoft.com/de-de/library/ff597918(v=vs.85).aspx

    【讨论】:

    • 你能帮帮我吗?似乎 WPD_STORAGE_CAPACITY_IN_OBJECTS 不起作用。
    猜你喜欢
    • 1970-01-01
    • 2019-07-09
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多