{"id":212,"date":"2009-07-10T11:33:24","date_gmt":"2009-07-10T09:33:24","guid":{"rendered":"http:\/\/dev.flauschig.ch\/wordpress\/?p=212"},"modified":"2009-08-21T09:05:14","modified_gmt":"2009-08-21T07:05:14","slug":"copymove-files-from-portabledevice","status":"publish","type":"post","link":"http:\/\/dev.flauschig.ch\/wordpress\/?p=212","title":{"rendered":"Copy\/Move Files from Portable Device"},"content":{"rendered":"<p>I tried to make a simple Application which connects to my Digital Camera (which is detected as Portable Device) and Copy or Move the Files to my Harddisk (and put them in Directories, named by the DateTaken of the Photo). At first I tried to use the .NET <code>FolderBrowserDialog<\/code> but it was soon clear, that it can&#8217;t handle Portable Devices and doesn&#8217;t even show them.<\/p>\n<p>My approach was to use the <code>shell32.dll<\/code>. It contains a <code>BrowseForFolder<\/code> which is able to handle Portable Devices. <!--more--><\/p>\n<p>To use it, just a add Reference to the COM Component <code>\"Microsoft Shell Controls and Automation\"<\/code> and include the <code>Shell32<\/code> Namespace.<\/p>\n<p>You can now call the BrowseForFolder with this Snippet:<\/p>\n<pre class=\"brush: csharp; gutter: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\nShell shell = new ShellClass();\r\nFolder folder = shell.BrowseForFolder((int)Hwnd, &quot;Choose Folder&quot;, 0, 0);\r\nif (folder == null)\r\n    \/\/ User cancelled\r\n<\/pre>\n<p>(Hwnd is just a Handle to a Form)<br \/>\nNote that the <code>Folder<\/code> is a COM-Object so you can&#8217;t use it like a .Net Directory.<\/p>\n<p>You can get the Path out of it by Casting it to a FolderItem:<\/p>\n<pre class=\"brush: csharp; gutter: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\nFolderItem fi = (folder as Folder3).Self;\r\nstring path = fi.Path;\r\n<\/pre>\n<p>This Path for my DigitalCamera was like: <code>\"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\\\\?\\usb#vid_04a9&pid_3137#3b1feaedb9f64d6a9dd782783b9bcecd#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\\SID-{10001,,4066902016}\\{00000003-0000-0000-0000-000000000000}\\{00000004-0000-0000-0000-000000000000}\\{00000005-0000-0000-0000-000000000000}\"<\/code><br \/>\nSelecting a Folder on the Harddisk results in a normal Path like: <code>\"C:\\Temp\"<\/code><br \/>\nFor the first case, I found no possibility to use this &#8220;Path&#8221; to get a .Net Directory. That&#8217;s why I had to stick with the Shell32.Folder for copying \/ moving.<\/p>\n<p>You can now iterate through the Files with <code>folder.Items()<\/code> but again, the <code>FolderItem<\/code> Objects in this List are COM-Objects and I haven&#8217;t found any way to convert them to a .Net File.<\/p>\n<p>I used another approach: The COM-Folder-Object has two handy functions: <code>CopyHere<\/code> and <code>MoveHere<\/code>.<br \/>\nSo all I needed to do is to get a Source and a Target COM-Folder and call the CopyHere on the Target with the FolderItems from the Source Folder.<br \/>\nHere&#8217;s a Snippet for that:<\/p>\n<pre class=\"brush: csharp; gutter: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic static void CopyFiles(Folder srcFolder, Folder dstFolder)\r\n{\r\n\tforeach (FolderItem currFolderItem in srcFolder.Items())\r\n\t{\r\n\t\tdstFolder.CopyHere(currFolderItem, 0);\r\n\t}\r\n}\r\n<\/pre>\n<p>CopyHere and MoveHere have two Parameters, the second is the Options. Here&#8217;s an Enum with the possible Options I found so far:<\/p>\n<pre class=\"brush: csharp; collapse: true; gutter: false; light: false; title: ; toolbar: true; wrap-lines: false; notranslate\" title=\"\">\r\npublic enum CopyHereOptions\r\n{\r\n\tDefault = 0, \/\/ No Options specified\r\n\tNoProgressDialog = 4, \/\/ Do not display a Progress DialogBox\r\n\tRenameTarget = 8, \/\/ Rename the Target File if a File exists at the Target Location with the same Name\r\n\tAutoYesToAll = 16, \/\/ Click &quot;Yes to All&quot; in any DialogBox displayed\r\n\tPreserveUndo = 64, \/\/ Preserve undo Information, if possible\r\n\tWildcardOnly = 128, \/\/ Perform the Operation only if a Wildcard Filename (*.*) is specified\r\n\tHideProgressFileNames = 256, \/\/ Display a Progress DialogBox but do not show the Filenames\r\n\tNoNewFolderConfirmation = 512, \/\/ Do not confirm the creation of a new Directory if needed\r\n\tNoUIonError = 1024, \/\/ Do not display a User Interface if an Error occurs\r\n\tDisableRecursion = 4096, \/\/ Disable Recursion\r\n\tNoGroupCopy = 9182 \/\/ Do not copy connected Files as a Group. Only copy the specified Files\r\n}\r\n<\/pre>\n<p>In case you have a normal FolderPath and need it to be converted to a COM-Folder-Object, use this Snippet:<\/p>\n<pre class=\"brush: csharp; gutter: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic static Folder Path2Folder(string path)\r\n{\r\n\t\/\/ Create Folder if needed\r\n\tDirectory.CreateDirectory(path);\r\n\t\/\/ Create ShellObject\r\n\tShell shell = new ShellClass();\r\n\t\/\/ Convert to Shell Folder\r\n\treturn shell.NameSpace(path);\r\n}\r\n<\/pre>\n<p>That&#8217;s it, now all the Files are copied (or moved) from the Source to the Target. And after that, you can use a normal .Net Directory(Info) on your Target (which should be a normal FolderPath) to Access the Files with .Net.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I tried to make a simple Application which connects to my Digital Camera (which is detected as Portable Device) and Copy or Move the Files to my Harddisk (and put them in Directories, named by the DateTaken of the Photo). At first I tried to use the .NET FolderBrowserDialog but it was soon clear, that &hellip; <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[4,3],"tags":[87,83,84,86,85,88],"class_list":{"0":"entry","1":"post","2":"publish","3":"author-roemer","4":"has-more-link","5":"post-212","7":"format-standard","8":"category-csharp","9":"category-programming","10":"post_tag-browseforfolder","11":"post_tag-digicam","12":"post_tag-digital-camera","13":"post_tag-files","14":"post_tag-portable-device","15":"post_tag-shell32"},"acf":[],"views":38644,"_links":{"self":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/212"}],"collection":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=212"}],"version-history":[{"count":0,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/212\/revisions"}],"wp:attachment":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=212"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}