├── WindowsPortableDeviceNet ├── Model │ ├── Properties │ │ ├── NameProperty.cs │ │ ├── Device │ │ │ ├── ModelProperty.cs │ │ │ ├── ManufacturerProperty.cs │ │ │ ├── SerialNumberProperty.cs │ │ │ ├── FriendlyNameProperty.cs │ │ │ ├── FirmwareVersionProperty.cs │ │ │ └── TypeProperty.cs │ │ ├── OriginalFileNameProperty.cs │ │ ├── BaseWPDProperties.cs │ │ └── ContentTypeProperty.cs │ ├── WindowsPortableDeviceEnumerators.cs │ ├── BaseDeviceItem.cs │ ├── Item.cs │ └── Device.cs ├── Utility.cs ├── Properties │ └── AssemblyInfo.cs └── WindowsPortableDeviceNet.csproj ├── WindowsPortableDeviceNet.Test ├── Properties │ └── AssemblyInfo.cs ├── UtilityTest.cs └── WindowsPortableDeviceNet.Test.csproj ├── README.md ├── WindowsPortableDeviceNet.sln └── .gitignore /WindowsPortableDeviceNet/Model/Properties/NameProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model.Properties 5 | { 6 | public class NameProperty : BaseWPDProperties 7 | { 8 | public string Value { get; private set; } 9 | 10 | public NameProperty(IPortableDeviceValues deviceProperties) 11 | : base(deviceProperties) 12 | { 13 | FormatId = new Guid("EF6B490D-5CD8-437A-AFFC-DA8B60EE4A3C"); 14 | PositionId = 4; 15 | Value = GetStringPropertyValue(FormatId, PositionId); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Properties/Device/ModelProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model.Properties.Device 5 | { 6 | public class ModelProperty : BaseWPDProperties 7 | { 8 | public string Value { get; private set; } 9 | 10 | public ModelProperty(IPortableDeviceValues deviceProperties) 11 | : base(deviceProperties) 12 | { 13 | FormatId = new Guid("26D4979A-E643-4626-9E2B-736DC0C92FDC"); 14 | PositionId = 8; 15 | Value = GetStringPropertyValue(FormatId, PositionId); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Properties/Device/ManufacturerProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model.Properties.Device 5 | { 6 | public class ManufacturerProperty : BaseWPDProperties 7 | { 8 | public string Value { get; private set; } 9 | 10 | public ManufacturerProperty(IPortableDeviceValues deviceProperties) 11 | : base(deviceProperties) 12 | { 13 | FormatId = new Guid("26D4979A-E643-4626-9E2B-736DC0C92FDC"); 14 | PositionId = 7; 15 | Value = GetStringPropertyValue(FormatId, PositionId); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Properties/Device/SerialNumberProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model.Properties.Device 5 | { 6 | public class SerialNumberProperty : BaseWPDProperties 7 | { 8 | public string Value { get; private set; } 9 | 10 | public SerialNumberProperty(IPortableDeviceValues deviceProperties) 11 | : base(deviceProperties) 12 | { 13 | FormatId = new Guid("26D4979A-E643-4626-9E2B-736DC0C92FDC"); 14 | PositionId = 9; 15 | Value = GetStringPropertyValue(FormatId, PositionId); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Properties/OriginalFileNameProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model.Properties 5 | { 6 | public class OriginalFileNameProperty : BaseWPDProperties 7 | { 8 | public string Value { get; private set; } 9 | 10 | public OriginalFileNameProperty(IPortableDeviceValues deviceProperties) 11 | : base(deviceProperties) 12 | { 13 | FormatId = new Guid("EF6B490D-5CD8-437A-AFFC-DA8B60EE4A3C"); 14 | PositionId = 12; 15 | Value = GetStringPropertyValue(FormatId, PositionId); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Properties/Device/FriendlyNameProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model.Properties.Device 5 | { 6 | public class FriendlyNameProperty : BaseWPDProperties 7 | { 8 | public string Value { get; private set; } 9 | 10 | public FriendlyNameProperty(IPortableDeviceValues deviceProperties) 11 | : base(deviceProperties) 12 | { 13 | FormatId = new Guid("26D4979A-E643-4626-9E2B-736DC0C92FDC"); 14 | PositionId = 12; 15 | Value = GetStringPropertyValue(FormatId, PositionId); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Properties/Device/FirmwareVersionProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model.Properties.Device 5 | { 6 | public class FirmwareVersionProperty : BaseWPDProperties 7 | { 8 | public string Value { get; private set; } 9 | 10 | public FirmwareVersionProperty(IPortableDeviceValues deviceProperties) 11 | : base(deviceProperties) 12 | { 13 | FormatId = new Guid("26D4979A-E643-4626-9E2B-736DC0C92FDC"); 14 | PositionId = 3; 15 | Value = GetStringPropertyValue(FormatId, PositionId); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Utility.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using PortableDeviceApiLib; 3 | using WindowsPortableDeviceNet.Model; 4 | 5 | namespace WindowsPortableDeviceNet 6 | { 7 | public class Utility 8 | { 9 | public List Get() 10 | { 11 | List connectedPortableDevices = new List(); 12 | PortableDeviceManager manager = new PortableDeviceManager(); 13 | 14 | manager.RefreshDeviceList(); 15 | uint count = 1; 16 | manager.GetDevices(null, ref count); 17 | 18 | if (count == 0) return connectedPortableDevices; 19 | 20 | // Call the above again because we now know how many devices there are. 21 | 22 | string[] deviceIds = new string[count]; 23 | manager.GetDevices(ref deviceIds[0], ref count); 24 | 25 | ExtractDeviceInformation(deviceIds, connectedPortableDevices); 26 | return connectedPortableDevices; 27 | } 28 | 29 | private void ExtractDeviceInformation(string[] deviceIds, List connectedPortableDevices) 30 | { 31 | foreach (string deviceId in deviceIds) 32 | { 33 | connectedPortableDevices.Add(new Device(deviceId)); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/WindowsPortableDeviceEnumerators.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace WindowsPortableDeviceNet.Model 3 | { 4 | public class WindowsPortableDeviceEnumerators 5 | { 6 | public enum ContentType 7 | { 8 | Unknown = 0, 9 | FunctionalObject, 10 | Folder, 11 | Image, 12 | Document, 13 | Contact, 14 | ContactGroup, 15 | Audio, 16 | Video, 17 | Television, 18 | Playlist, 19 | MixedContentAlbum, 20 | AudioAlbum, 21 | ImageAlbum, 22 | VideoAlbum, 23 | Memo, 24 | Email, 25 | Appointment, 26 | Task, 27 | Program, 28 | GenericFile, 29 | Calendar, 30 | GenericMessage, 31 | NetworkAssociation, 32 | Certificate, 33 | WirelessProfile, 34 | MediaCast, 35 | Section, 36 | Unspecified, 37 | All 38 | }; 39 | 40 | public enum DeviceType 41 | { 42 | Unknown = 0, 43 | Generic, 44 | Camera, 45 | MediaPlayer, 46 | Phone, 47 | Video, 48 | PersonalInformationManager, 49 | AudioRecorder 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/BaseDeviceItem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model 5 | { 6 | public class BaseDeviceItem 7 | { 8 | public string Id { get; protected set; } 9 | public List DeviceItems { get; private set; } 10 | 11 | public BaseDeviceItem(string id) 12 | { 13 | Id = id; 14 | DeviceItems = new List(); 15 | } 16 | 17 | /// 18 | /// This method enumerates/cycles through sub objects within this current object. 19 | /// 20 | /// 21 | protected void LoadDeviceItems(IPortableDeviceContent content) 22 | { 23 | // Enumerate the items contained by the current object 24 | 25 | IEnumPortableDeviceObjectIDs objectIds; 26 | content.EnumObjects(0, Id, null, out objectIds); 27 | 28 | // Cycle through each device item and add it to the device items list. 29 | 30 | uint fetched = 0; 31 | do 32 | { 33 | string objectId; 34 | objectIds.Next(1, out objectId, ref fetched); 35 | 36 | // Check if anything was retrieved. 37 | 38 | if (fetched > 0) 39 | { 40 | DeviceItems.Add(new Item(objectId, content)); 41 | } 42 | } while (fetched > 0); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("WindowsPortableDeviceNet")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Toshiba")] 11 | [assembly: AssemblyProduct("WindowsPortableDeviceNet")] 12 | [assembly: AssemblyCopyright("Copyright © Toshiba 2012")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("c33cc1fe-6422-469e-b47b-7eb5598aa4b7")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.5.0")] 35 | [assembly: AssemblyFileVersion("1.0.5.0")] 36 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WindowsPortableDeviceNet.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Toshiba")] 12 | [assembly: AssemblyProduct("WindowsPortableDeviceNet.Test")] 13 | [assembly: AssemblyCopyright("Copyright © Toshiba 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f6508355-e75b-4da0-bea0-d983f3398e27")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WPD-.NET-Wrapper 2 | ================ 3 | 4 | Windows Portable Device .Net Wrapper 5 | 6 | ## Current State 7 | 8 | Hi, to all the users that wish to use this library please feel free. 9 | Unfortunately it has been a while since I've looked at this and I can't really remember how it all works. 10 | I might get back to it someday but for now I'm not really keeping it up to date. 11 | 12 | ## Copyright 13 | 14 | Copyright (c) 2013 Gavin Chin (slowmonkey - https://github.com/slowmonkey) 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining 17 | a copy of this software and associated documentation files (the 18 | "Software"), to deal in the Software without restriction, including 19 | without limitation the rights to use, copy, modify, merge, publish, 20 | distribute, sublicense, and/or sell copies of the Software, and to 21 | permit persons to whom the Software is furnished to do so, subject to 22 | the following conditions: 23 | 24 | The above copyright notice and this permission notice shall be 25 | included in all copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 29 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 31 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 32 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 33 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 34 | 35 | ------------ 36 | ADDITIONAL INFORMATION BEFORE I FORGET: 37 | - Apparently there is a device simulator now for "Windows 7 Portable Device Enabling Kit for MTP, Verions 7R2", http://msdn.microsoft.com/en-us/library/windows/hardware/Dn614016(v=vs.85).aspx 38 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Properties/BaseWPDProperties.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model.Properties 5 | { 6 | public class BaseWPDProperties 7 | { 8 | public IPortableDeviceValues DeviceProperties { get; private set; } 9 | 10 | public Guid FormatId { get; set; } 11 | public uint PositionId { get; set; } 12 | 13 | public BaseWPDProperties(IPortableDeviceValues deviceProperties) 14 | { 15 | DeviceProperties = deviceProperties; 16 | } 17 | 18 | public string GetStringPropertyValue(Guid formatId, uint positionId) 19 | { 20 | _tagpropertykey property = CreateProperty(formatId, positionId); 21 | 22 | string propertyValue; 23 | DeviceProperties.GetStringValue(ref property, out propertyValue); 24 | return propertyValue; 25 | } 26 | 27 | public Guid GetGUIDPropertyValue(Guid formatId, uint positionId) 28 | { 29 | _tagpropertykey property = CreateProperty(formatId, positionId); 30 | 31 | Guid propertyValue; 32 | DeviceProperties.GetGuidValue(ref property, out propertyValue); 33 | return propertyValue; 34 | } 35 | 36 | public uint GetUIntPropertyValue(Guid formatId, uint positionId) 37 | { 38 | _tagpropertykey property = CreateProperty(formatId, positionId); 39 | 40 | uint propertyValue; 41 | DeviceProperties.GetUnsignedIntegerValue(ref property, out propertyValue); 42 | return propertyValue; 43 | } 44 | 45 | public static _tagpropertykey CreateProperty(Guid formatId, uint positionId) 46 | { 47 | return new PortableDeviceApiLib._tagpropertykey() 48 | { 49 | fmtid = formatId, 50 | pid = positionId, 51 | }; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsPortableDeviceNet", "WindowsPortableDeviceNet\WindowsPortableDeviceNet.csproj", "{A1B70228-1986-4AD2-A4AC-9C54DE223E6F}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsPortableDeviceNet.Test", "WindowsPortableDeviceNet.Test\WindowsPortableDeviceNet.Test.csproj", "{38329864-18F2-4D14-94B0-0D5C24B0AA8D}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7A836758-6EC6-4399-9613-12F765076778}" 9 | ProjectSection(SolutionItems) = preProject 10 | Local.testsettings = Local.testsettings 11 | TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings 12 | WindowsPortableDeviceNet.vsmdi = WindowsPortableDeviceNet.vsmdi 13 | EndProjectSection 14 | EndProject 15 | Global 16 | GlobalSection(TestCaseManagementSettings) = postSolution 17 | CategoryFile = WindowsPortableDeviceNet.vsmdi 18 | EndGlobalSection 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {A1B70228-1986-4AD2-A4AC-9C54DE223E6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {A1B70228-1986-4AD2-A4AC-9C54DE223E6F}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {A1B70228-1986-4AD2-A4AC-9C54DE223E6F}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {A1B70228-1986-4AD2-A4AC-9C54DE223E6F}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {38329864-18F2-4D14-94B0-0D5C24B0AA8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {38329864-18F2-4D14-94B0-0D5C24B0AA8D}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {38329864-18F2-4D14-94B0-0D5C24B0AA8D}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {38329864-18F2-4D14-94B0-0D5C24B0AA8D}.Release|Any CPU.Build.0 = Release|Any CPU 32 | EndGlobalSection 33 | GlobalSection(SolutionProperties) = preSolution 34 | HideSolutionNode = FALSE 35 | EndGlobalSection 36 | EndGlobal 37 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet.Test/UtilityTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Forms; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using WindowsPortableDeviceNet.Model; 5 | 6 | namespace WindowsPortableDeviceNet.Test 7 | { 8 | [TestClass] 9 | public class UtilityTest 10 | { 11 | [TestMethod] 12 | [TestCategory("Integration")] 13 | public void Get_GetConnectedDevices_1DeviceDetected() 14 | { 15 | MessageBox.Show( 16 | "Please ensure that a camera is connected.", 17 | "Test Message", 18 | MessageBoxButtons.OK, 19 | MessageBoxIcon.Stop); 20 | Utility utility = new Utility(); 21 | List device = utility.Get(); 22 | 23 | Assert.AreEqual(1, device.Count); 24 | } 25 | 26 | [TestMethod] 27 | [TestCategory("Integration")] 28 | public void TransferData_WithNoFolderStructure_OnlyFilesCopied() 29 | { 30 | MessageBox.Show( 31 | "Please ensure that a camera is connected.", 32 | "Test Message", 33 | MessageBoxButtons.OK, 34 | MessageBoxIcon.Stop); 35 | Utility utility = new Utility(); 36 | List device = utility.Get(); 37 | device[0].Connect(); 38 | device[0].TransferData("C:\\Users\\Gav\\Desktop\\test", isKeepFolderStructure: false); 39 | device[0].Disconnect(); 40 | } 41 | 42 | [TestMethod] 43 | [TestCategory("Integration")] 44 | public void TransferData_WithFolderStructure_FilesCopiedWithFolderStructure() 45 | { 46 | MessageBox.Show( 47 | "Please ensure that a camera is connected.", 48 | "Test Message", 49 | MessageBoxButtons.OK, 50 | MessageBoxIcon.Stop); 51 | Utility utility = new Utility(); 52 | List device = utility.Get(); 53 | device[0].Connect(); 54 | device[0].TransferData("C:\\Users\\Gav\\Desktop\\test", isKeepFolderStructure: true); 55 | device[0].Disconnect(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Properties/Device/TypeProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PortableDeviceApiLib; 3 | 4 | namespace WindowsPortableDeviceNet.Model.Properties.Device 5 | { 6 | /// 7 | /// This class extracts the device type property from the windows portable device 8 | /// 9 | public class TypeProperty : BaseWPDProperties 10 | { 11 | // These uint values are obtained from the Windows Driver Kit Tools - WpdInfo.Values file. 12 | 13 | private enum WpdDeviceType 14 | { 15 | Generic = 0, 16 | Camera = 1, 17 | MediaPlayer = 2, 18 | Phone = 3, 19 | Video = 4, 20 | PersonalInformationManager = 5, 21 | AudioRecorder = 6, 22 | }; 23 | 24 | public WindowsPortableDeviceEnumerators.DeviceType Type { get; private set; } 25 | public uint Value { get; private set; } 26 | 27 | public TypeProperty(IPortableDeviceValues deviceProperties) 28 | : base(deviceProperties) 29 | { 30 | FormatId = new Guid("26D4979A-E643-4626-9E2B-736DC0C92FDC"); 31 | PositionId = 15; 32 | Value = GetUIntPropertyValue(FormatId, PositionId); 33 | ExtrapolateDeviceType(Value); 34 | } 35 | 36 | private void ExtrapolateDeviceType(uint deviceType) 37 | { 38 | switch ((WpdDeviceType)deviceType) 39 | { 40 | case WpdDeviceType.Generic: 41 | { 42 | Type = WindowsPortableDeviceEnumerators.DeviceType.Generic; 43 | } 44 | break; 45 | 46 | case WpdDeviceType.Camera: 47 | { 48 | Type = WindowsPortableDeviceEnumerators.DeviceType.Camera; 49 | } 50 | break; 51 | 52 | case WpdDeviceType.MediaPlayer: 53 | { 54 | Type = WindowsPortableDeviceEnumerators.DeviceType.MediaPlayer; 55 | } 56 | break; 57 | 58 | case WpdDeviceType.Phone: 59 | { 60 | Type = WindowsPortableDeviceEnumerators.DeviceType.Phone; 61 | } 62 | break; 63 | 64 | case WpdDeviceType.Video: 65 | { 66 | Type = WindowsPortableDeviceEnumerators.DeviceType.Video; 67 | } 68 | break; 69 | 70 | case WpdDeviceType.PersonalInformationManager: 71 | { 72 | Type = WindowsPortableDeviceEnumerators.DeviceType.PersonalInformationManager; 73 | } 74 | break; 75 | 76 | case WpdDeviceType.AudioRecorder: 77 | { 78 | Type = WindowsPortableDeviceEnumerators.DeviceType.AudioRecorder; 79 | } 80 | break; 81 | 82 | default: 83 | { 84 | Type = WindowsPortableDeviceEnumerators.DeviceType.Unknown; 85 | } 86 | break; 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet.Test/WindowsPortableDeviceNet.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 7 | 8 | 2.0 9 | {38329864-18F2-4D14-94B0-0D5C24B0AA8D} 10 | Library 11 | Properties 12 | WindowsPortableDeviceNet.Test 13 | WindowsPortableDeviceNet.Test 14 | v4.0 15 | 512 16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 3.5 40 | 41 | 42 | 43 | 44 | 45 | False 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {A1B70228-1986-4AD2-A4AC-9C54DE223E6F} 55 | WindowsPortableDeviceNet 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/WindowsPortableDeviceNet.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {A1B70228-1986-4AD2-A4AC-9C54DE223E6F} 9 | Library 10 | Properties 11 | WindowsPortableDeviceNet 12 | WindowsPortableDeviceNet 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | true 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | {1F001332-1A57-4934-BE31-AFFC99F4EE0A} 65 | 1 66 | 0 67 | 0 68 | tlbimp 69 | False 70 | False 71 | 72 | 73 | {2B00BA2F-E750-4BEB-9235-97142EDE1D3E} 74 | 1 75 | 0 76 | 0 77 | tlbimp 78 | False 79 | False 80 | 81 | 82 | 83 | 84 | 91 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Properties/ContentTypeProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using PortableDeviceApiLib; 4 | 5 | namespace WindowsPortableDeviceNet.Model.Properties 6 | { 7 | /// 8 | /// This class extracts the device type property from the windows portable device 9 | /// 10 | public class ContentTypeProperty : BaseWPDProperties 11 | { 12 | private static readonly Dictionary WpdContentTypeGuids = 13 | new Dictionary 14 | { 15 | {"99ED0160-17FF-4C44-9D98-1D7A6F941921", WindowsPortableDeviceEnumerators.ContentType.FunctionalObject}, 16 | {"27E2E392-A111-48E0-AB0C-E17705A05F85", WindowsPortableDeviceEnumerators.ContentType.Folder}, 17 | {"EF2107D5-A52A-4243-A26B-62D4176D7603", WindowsPortableDeviceEnumerators.ContentType.Image}, 18 | {"680ADF52-950A-4041-9B41-65E393648155", WindowsPortableDeviceEnumerators.ContentType.Document}, 19 | {"EABA8313-4525-4707-9F0E-87C6808E9435", WindowsPortableDeviceEnumerators.ContentType.Contact}, 20 | {"346B8932-4C36-40D8-9415-1828291F9DE9", WindowsPortableDeviceEnumerators.ContentType.ContactGroup}, 21 | {"4AD2C85E-5E2D-45E5-8864-4F229E3C6CF0", WindowsPortableDeviceEnumerators.ContentType.Audio}, 22 | {"9261B03C-3D78-4519-85E3-02C5E1F50BB9", WindowsPortableDeviceEnumerators.ContentType.Video}, 23 | {"60A169CF-F2AE-4E21-9375-9677F11C1C6E", WindowsPortableDeviceEnumerators.ContentType.Television}, 24 | {"1A33F7E4-AF13-48F5-994E-77369DFE04A3", WindowsPortableDeviceEnumerators.ContentType.Playlist}, 25 | {"00F0C3AC-A593-49AC-9219-24ABCA5A2563", WindowsPortableDeviceEnumerators.ContentType.MixedContentAlbum}, 26 | {"AA18737E-5009-48FA-AE21-85F24383B4E6", WindowsPortableDeviceEnumerators.ContentType.AudioAlbum}, 27 | {"75793148-15F5-4A30-A813-54ED8A37E226", WindowsPortableDeviceEnumerators.ContentType.ImageAlbum}, 28 | {"012B0DB7-D4C1-45D6-B081-94B87779614F", WindowsPortableDeviceEnumerators.ContentType.VideoAlbum}, 29 | {"9CD20ECF-3B50-414F-A641-E473FFE45751", WindowsPortableDeviceEnumerators.ContentType.Memo}, 30 | {"8038044A-7E51-4F8F-883D-1D0623D14533", WindowsPortableDeviceEnumerators.ContentType.Email}, 31 | {"0FED060E-8793-4B1E-90C9-48AC389AC631", WindowsPortableDeviceEnumerators.ContentType.Appointment}, 32 | {"63252F2C-887F-4CB6-B1AC-D29855DCEF6C", WindowsPortableDeviceEnumerators.ContentType.Task}, 33 | {"D269F96A-247C-4BFF-98FB-97F3C49220E6", WindowsPortableDeviceEnumerators.ContentType.Program}, 34 | {"0085E0A6-8D34-45D7-BC5C-447E59C73D48", WindowsPortableDeviceEnumerators.ContentType.GenericFile}, 35 | {"A1FD5967-6023-49A0-9DF1-F8060BE751B0", WindowsPortableDeviceEnumerators.ContentType.Calendar}, 36 | {"E80EAAF8-B2DB-4133-B67E-1BEF4B4A6E5F", WindowsPortableDeviceEnumerators.ContentType.GenericMessage}, 37 | {"031DA7EE-18C8-4205-847E-89A11261D0F3", WindowsPortableDeviceEnumerators.ContentType.NetworkAssociation}, 38 | {"DC3876E8-A948-4060-9050-CBD77E8A3D87", WindowsPortableDeviceEnumerators.ContentType.Certificate}, 39 | {"0BAC070A-9F5F-4DA4-A8F6-3DE44D68FD6C", WindowsPortableDeviceEnumerators.ContentType.WirelessProfile}, 40 | {"5E88B3CC-3E65-4E62-BFFF-229495253AB0", WindowsPortableDeviceEnumerators.ContentType.MediaCast}, 41 | {"821089F5-1D91-4DC9-BE3C-BBB1B35B18CE", WindowsPortableDeviceEnumerators.ContentType.Section}, 42 | {"28D8D31E-249C-454E-AABC-34883168E634", WindowsPortableDeviceEnumerators.ContentType.Unspecified}, 43 | {"80E170D2-1055-4A3E-B952-82CC4F8A8689", WindowsPortableDeviceEnumerators.ContentType.All} 44 | }; 45 | 46 | public WindowsPortableDeviceEnumerators.ContentType Type { get; private set; } 47 | public string Value { get; private set; } 48 | 49 | public ContentTypeProperty(IPortableDeviceValues deviceProperties) 50 | : base(deviceProperties) 51 | { 52 | FormatId = new Guid("EF6B490D-5CD8-437A-AFFC-DA8B60EE4A3C"); 53 | PositionId = 7; 54 | Value = GetGUIDPropertyValue(FormatId, PositionId).ToString(); 55 | ExtrapolateDeviceType(Value); 56 | } 57 | 58 | 59 | private void ExtrapolateDeviceType(string deviceType) 60 | { 61 | if (WpdContentTypeGuids.ContainsKey(deviceType.ToUpper())) 62 | { 63 | Type = WpdContentTypeGuids[deviceType.ToUpper()]; 64 | } 65 | else 66 | { 67 | Type = WindowsPortableDeviceEnumerators.ContentType.Unknown; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Item.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.InteropServices; 4 | using PortableDeviceApiLib; 5 | using WindowsPortableDeviceNet.Model.Properties; 6 | 7 | namespace WindowsPortableDeviceNet.Model 8 | { 9 | public class Item : BaseDeviceItem 10 | { 11 | public ContentTypeProperty ContentType { get; set; } 12 | public NameProperty Name { get; set; } 13 | public OriginalFileNameProperty OriginalFileName { get; set; } 14 | 15 | private IPortableDeviceContent DeviceContent { get; set; } 16 | 17 | public Item(string objectId, IPortableDeviceContent content) 18 | : base(objectId) 19 | { 20 | DeviceContent = content; 21 | 22 | IPortableDeviceProperties properties; 23 | content.Properties(out properties); 24 | 25 | IPortableDeviceKeyCollection keys; 26 | properties.GetSupportedProperties(objectId, out keys); 27 | 28 | IPortableDeviceValues values; 29 | properties.GetValues(objectId, keys, out values); 30 | 31 | ContentType = new ContentTypeProperty(values); 32 | Name = new NameProperty(values); 33 | 34 | // Only load the sub information if the current object is a folder or functional object. 35 | 36 | switch (ContentType.Type) 37 | { 38 | case WindowsPortableDeviceEnumerators.ContentType.FunctionalObject: 39 | { 40 | LoadDeviceItems(content); 41 | break; 42 | } 43 | 44 | case WindowsPortableDeviceEnumerators.ContentType.Folder: 45 | { 46 | OriginalFileName = new OriginalFileNameProperty(values); 47 | LoadDeviceItems(content); 48 | break; 49 | } 50 | 51 | case WindowsPortableDeviceEnumerators.ContentType.Image: 52 | { 53 | OriginalFileName = new OriginalFileNameProperty(values); 54 | break; 55 | } 56 | } 57 | } 58 | 59 | public void TransferFiles(string destinationPath, bool isKeepFolderStructure) 60 | { 61 | switch (ContentType.Type) 62 | { 63 | case WindowsPortableDeviceEnumerators.ContentType.Folder: 64 | case WindowsPortableDeviceEnumerators.ContentType.FunctionalObject: 65 | { 66 | if (isKeepFolderStructure) 67 | { 68 | destinationPath = Path.Combine(destinationPath, Name.Value); 69 | if (!Directory.Exists(destinationPath)) 70 | { 71 | Directory.CreateDirectory(destinationPath); 72 | } 73 | } 74 | 75 | foreach (Item item in DeviceItems) 76 | { 77 | item.TransferFiles(destinationPath, isKeepFolderStructure); 78 | } 79 | } 80 | break; 81 | 82 | case WindowsPortableDeviceEnumerators.ContentType.Image: 83 | { 84 | TransferFile(destinationPath); 85 | } 86 | break; 87 | } 88 | } 89 | 90 | /// 91 | /// This method copies the file from the device to the destination path. 92 | /// 93 | /// 94 | private void TransferFile(string destinationPath) 95 | { 96 | // TODO: Clean this up. 97 | 98 | IPortableDeviceResources resources; 99 | DeviceContent.Transfer(out resources); 100 | 101 | IStream wpdStream = null; 102 | uint optimalTransferSize = 0; 103 | 104 | var property = new _tagpropertykey 105 | { 106 | fmtid = new Guid("E81E79BE-34F0-41BF-B53F-F1A06AE87842"), 107 | pid = 0 108 | }; 109 | 110 | System.Runtime.InteropServices.ComTypes.IStream sourceStream = null; 111 | try 112 | { 113 | resources.GetStream(Id, ref property, 0, ref optimalTransferSize, out wpdStream); 114 | sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream; 115 | 116 | FileStream targetStream = new FileStream( 117 | Path.Combine(destinationPath, OriginalFileName.Value), 118 | FileMode.Create, 119 | FileAccess.Write); 120 | 121 | unsafe 122 | { 123 | try 124 | { 125 | var buffer = new byte[1024]; 126 | int bytesRead; 127 | do 128 | { 129 | sourceStream.Read(buffer, 1024, new IntPtr(&bytesRead)); 130 | targetStream.Write(buffer, 0, 1024); 131 | } while (bytesRead > 0); 132 | } 133 | finally 134 | { 135 | targetStream.Close(); 136 | } 137 | } 138 | } 139 | finally 140 | { 141 | Marshal.ReleaseComObject(sourceStream); 142 | Marshal.ReleaseComObject(wpdStream); 143 | } 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /WindowsPortableDeviceNet/Model/Device.cs: -------------------------------------------------------------------------------- 1 | using PortableDeviceApiLib; 2 | using PortableDeviceTypesLib; 3 | using WindowsPortableDeviceNet.Model.Properties; 4 | using WindowsPortableDeviceNet.Model.Properties.Device; 5 | using IPortableDeviceValues = PortableDeviceApiLib.IPortableDeviceValues; 6 | 7 | namespace WindowsPortableDeviceNet.Model 8 | { 9 | public class Device : BaseDeviceItem 10 | { 11 | public string DeviceId { get; set; } 12 | 13 | public ContentTypeProperty ContentType { get; set; } 14 | public TypeProperty DeviceType { get; set; } 15 | public FirmwareVersionProperty FirmwareVersion { get; private set; } 16 | public FriendlyNameProperty FriendlyName { get; private set; } 17 | public ManufacturerProperty Manufacturer { get; private set; } 18 | public ModelProperty Model { get; private set; } 19 | public NameProperty Name { get; private set; } 20 | public SerialNumberProperty SerialNumber { get; private set; } 21 | 22 | // COM related objects. 23 | 24 | private PortableDeviceClass ComDeviceObject { get; set; } 25 | public bool IsConnected { get; private set; } 26 | 27 | /// 28 | /// Construct the device by obtainin the device properties and the sub data. 29 | /// 30 | /// NOTE: 31 | /// There is a difference with the device id and the id. 32 | /// The id indicates the object id within the windows portable device. 33 | /// The device id indicates the object id within the operating system. 34 | /// 35 | /// The initial id for all windows portable devices is hard coded to "DEVICE" 36 | /// 37 | /// 38 | public Device(string deviceId) : base("DEVICE") 39 | { 40 | DeviceId = deviceId; 41 | ComDeviceObject = new PortableDeviceClass(); 42 | Connect(); 43 | IPortableDeviceValues deviceProperties = ExtractDeviceProperties(ComDeviceObject); 44 | 45 | ContentType = new ContentTypeProperty(deviceProperties); 46 | DeviceType = new TypeProperty(deviceProperties); 47 | FirmwareVersion = new FirmwareVersionProperty(deviceProperties); 48 | FriendlyName = new FriendlyNameProperty(deviceProperties); 49 | Manufacturer = new ManufacturerProperty(deviceProperties); 50 | Model = new ModelProperty(deviceProperties); 51 | Name = new NameProperty(deviceProperties); 52 | SerialNumber = new SerialNumberProperty(deviceProperties); 53 | 54 | LoadDeviceData(ComDeviceObject); 55 | 56 | Disconnect(); 57 | } 58 | 59 | /// 60 | /// This method opens a connection to the device. 61 | /// 62 | public void Connect() 63 | { 64 | if (IsConnected) { return; } 65 | 66 | var clientInfo = (IPortableDeviceValues)new PortableDeviceValuesClass(); 67 | ComDeviceObject.Open(DeviceId, clientInfo); 68 | IsConnected = true; 69 | } 70 | 71 | /// 72 | /// This method closes the connection to the device. 73 | /// 74 | public void Disconnect() 75 | { 76 | if (!IsConnected) { return; } 77 | ComDeviceObject.Close(); 78 | IsConnected = false; 79 | } 80 | 81 | /// 82 | /// This method transfers the data on the device to the destination path. 83 | /// 84 | /// 85 | /// 86 | public void TransferData(string destinationPath, bool isKeepFolderStructure) 87 | { 88 | try 89 | { 90 | Connect(); 91 | foreach (Item item in DeviceItems) 92 | { 93 | item.TransferFiles(destinationPath, isKeepFolderStructure); 94 | } 95 | } 96 | finally 97 | { 98 | Disconnect(); 99 | } 100 | } 101 | 102 | public void Refresh(string deviceId) 103 | { 104 | DeviceId = deviceId; 105 | DeviceItems.Clear(); 106 | 107 | try 108 | { 109 | Connect(); 110 | LoadDeviceData(ComDeviceObject); 111 | } 112 | finally 113 | { 114 | Disconnect(); 115 | } 116 | } 117 | 118 | /// 119 | /// This method gets the list of properties from the properties list that pertain only to the device. 120 | /// 121 | /// 122 | /// 123 | private IPortableDeviceValues ExtractDeviceProperties(PortableDeviceClass portableDeviceItem) 124 | { 125 | IPortableDeviceContent content; 126 | IPortableDeviceProperties properties; 127 | portableDeviceItem.Content(out content); 128 | content.Properties(out properties); 129 | 130 | // Retrieve the values for the properties 131 | 132 | IPortableDeviceValues propertyValues; 133 | properties.GetValues(Id, null, out propertyValues); 134 | 135 | return propertyValues; 136 | } 137 | 138 | /// 139 | /// This method loads the sub folders and files within the device. 140 | /// NOTE: It only loads the subfolder and file information. 141 | /// No actual binary is loaded as this could potentially be a very 142 | /// piece of data in memory. 143 | /// 144 | /// 145 | private void LoadDeviceData(PortableDeviceClass portableDeviceItem) 146 | { 147 | IPortableDeviceContent content; 148 | portableDeviceItem.Content(out content); 149 | LoadDeviceItems(content); 150 | } 151 | } 152 | } 153 | --------------------------------------------------------------------------------