[英]How to get MTP device Available Storage & Storage Capacity using C#?
I am using PortableDevice API to get the MTP Device detection and Device properties. 我正在使用PortableDevice API获取MTP设备检测和设备属性。 I want to get the MTP Device Storage like capacity of storage and available storage.Here is my sample code for getting the friendly name of the device is,
我想获得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;
}
}
Same way I want to read the Device storage and free space from the MTP device. 我想以同样的方式从MTP设备读取设备存储空间和可用空间。
I tried like this, but I am missing some thing, 我曾这样尝试过,但我缺少一些东西,
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);
...................................... ................................... ................................................................................... .......................
Thanks in advance. 提前致谢。
//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);
}
Just FYI this is some code to display supported propertykeys. 仅供参考,这是一些代码来显示支持的属性键。 If you pass the objectID not of the root folder, but of the first folder (in Explorer for example Internal Storage), you'll see
如果您传递的不是第一个文件夹的objectID,而是第一个文件夹(在Explorer中,例如Internal Storage),您将看到
WPD_STORAGE_CAPACITY _tagpropertykey
I highly recommend to make a class to store all PropertyKeys¹, it will do it much better looking. 我强烈建议创建一个类来存储所有PropertyKeys¹,这样做会更好看。
I think you probably should take a glance at cgeers tutorials, so I will take that as a base. 我认为您可能应该浏览一下cgeers教程,因此我将以此为基础。
Add a Root folder to your PortableDevice
class for easy access: 将Root文件夹添加到
PortableDevice
类中以便于访问:
private readonly PortableDeviceFolder root = new PortableDeviceFolder("DEVICE", "DEVICE"); public PortableDeviceFolder Root { get { return root; } }
Use that code for your folder objectId (as mentioned before for example Internal Storage) 使用该代码作为文件夹的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);
This code is very similar to parts of the Refresh method (and submethods) from cgeers, so your folder object has already to be created. 此代码与cgeers的Refresh方法(和子方法)的一部分非常相似,因此必须已经创建了文件夹对象。
The fact that you can retrieve this information from this folder is either pure knowledge/common sense (Win Explorer also shows the information on that folder) or can be learned by executing the first code lines at the top. 您可以从此文件夹中检索此信息的事实是纯粹的常识/常识(Win Explorer也显示该文件夹中的信息),或者可以通过执行顶部的第一行代码来学习。
I - for myself - changed the PortableDeviceFolder
structure, which now contains a Collection of PortableDeviceObject
s which are in the folder and each one also saves its parent. 我-我自己-更改了
PortableDeviceFolder
结构,该结构现在在文件夹中包含一个PortableDeviceObject
集合,每个文件夹还保存了其父文件夹。
Like that the access on folders is very easy, for example to get your desired folderId
I'd just use this code: 像这样,对文件夹的访问非常容易,例如,获得所需的
folderId
我将仅使用以下代码:
PortableDeviceCollection c = new PortableDeviceCollection();
c.Refresh();
PortableDevice device = c.First();
device.Root.RefreshFiles();
PortableDeviceFolder internalstorageFolder = (PortableDeviceFolder)device.Root.Files.First();
You can try to implement a structure like this yourself or go a completely other way, I think there is no perfect structure for access, so one needs to figure out what fits best. 您可以自己尝试实现这样的结构,也可以采用其他方法,我认为没有完美的访问结构,因此需要找出最合适的结构。
¹: https://github.com/gtaglang/WpdLib/blob/master/src/WpdLib/WpdProperties.cs ¹: https : //github.com/gtaglang/WpdLib/blob/master/src/WpdLib/WpdProperties.cs
²: https://msdn.microsoft.com/de-de/library/ff597918(v=vs.85).aspx ²: https : //msdn.microsoft.com/de-de/library/ff597918(v= vs.85) .aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.