public void DownloadFile(NwdPortableDeviceFile file, string saveToFolderPath) { if (!_isConnected) { Connect(); } IPortableDeviceContent content; this._device.Content(out content); IPortableDeviceResources resources; content.Transfer(out resources); PortableDeviceApiLib.IStream wpdStream; uint optimalTransferSize = 0; var property = new _tagpropertykey(); property.fmtid = new Guid(0xE81E79BE, 0x34F0, 0x41BF, 0xB5, 0x3F, 0xF1, 0xA0, 0x6A, 0xE8, 0x78, 0x42); property.pid = 0; resources.GetStream(file.Id, ref property, 0, ref optimalTransferSize, out wpdStream); System.Runtime.InteropServices.ComTypes.IStream sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream; var filename = Path.GetFileName(file.Name); //uses the name with extension (differs from tutorial version) FileStream targetStream = new FileStream(Path.Combine(saveToFolderPath, filename), FileMode.Create, FileAccess.Write); unsafe { //TODO: play with this value (bufferSize) // (I get different entries missing/invalid based on the // number used, there has to be a connection, probably // an encoding thing, need more research) // int bufferSize = 1024; //int bufferSize = 4096; int bufferSize = 8192; var buffer = new byte[bufferSize]; int bytesRead; do { sourceStream.Read(buffer, bufferSize, new IntPtr(&bytesRead)); targetStream.Write(buffer, 0, bytesRead); targetStream.Flush(); } while (bytesRead > 0); targetStream.Close(); } //TODO: LICENSE NOTES //see comments on: https://cgeers.wordpress.com/2011/08/13/wpd-transferring-content/ Marshal.ReleaseComObject(sourceStream); Marshal.ReleaseComObject(wpdStream); Disconnect(); }
private void MenuItemFindToBeRemovedPlayList_Click(object sender, RoutedEventArgs e) { //just supporting first attached device for now, can cycle through multiples later NwdPortableDeviceCollection col = new NwdPortableDeviceCollection(); try { col.Refresh(); } catch (Exception ex) { Display.Exception(ex); } if (col.Count() > 0) { NwdPortableDevice device = col.First(); if (device != null) { //if(unprocessedDeletions == null || // unprocessedDeletions.Count < 1) if (unprocessedDeletions.IsEmptyOrNull()) { toBeRemoved = GetFirstToBeRemovedPlaylist(); if (toBeRemoved == null) { MessageBox.Show("Playlist(s) 'to be removed[*]' not found"); } else { MessageBox.Show("found [" + toBeRemoved.Name + "]"); //copy file to local file system string localDestinationFolder = Configuration.PlaylistsFolder; device.DownloadFile(toBeRemoved, localDestinationFolder); string localFilePath = System.IO.Path.Combine(localDestinationFolder, toBeRemoved.Name); MessageBox.Show("copied file to [" + localFilePath + "]"); List<string> entries = File.ReadAllLines(localFilePath).ToList(); MessageBox.Show("found " + entries.Count + " entries"); List<NwdUri> lst = new List<NwdUri>(); List<string> invalidPaths = new List<string>(); foreach (string entry in entries) { NwdUri newUri = Configuration.NwdPathToNwdUri(entry); if (newUri != null) { lst.Add(newUri); } else { invalidPaths.Add(entry); } } var pathList = (from entry in invalidPaths select new { Path = entry }).ToList(); if (pathList.Count > 0) { Display.Grid(invalidPaths.Count + " invalid paths skipped", lst, pathList); } else { Display.Grid("0 invalid paths skipped", lst); } var processEntries = (from nwdUri in lst select new NwdUriProcessEntry(nwdUri)).ToList(); unprocessedDeletions = new Stack<NwdUriProcessEntry>(processEntries); } } else { MessageBox.Show(unprocessedDeletions.Count + " unprocessed entries found for [" + toBeRemoved.Name + "]"); } if (unprocessedDeletions != null) { List<NwdUriProcessEntry> processed = new List<NwdUriProcessEntry>(); bool again = true; string msg = "Enter processing segment size (keep in mind that " + "caching works better the higher this number is, but the " + "higher the number, the longer each iteration will obviously " + "take, find a balance that works for your device)"; while (again && unprocessedDeletions.Count() > 0) { int repetitionSegmentSize = NineWorldsDeep.UI.Prompt.ForInteger(msg); IEnumerable<NwdUriProcessEntry> currentlyProcessing = unprocessedDeletions.Pop(repetitionSegmentSize); Stopwatch watch = Stopwatch.StartNew(); var res = FindByUriCached(currentlyProcessing.ToNwdUris()); watch.Stop(); //just profiling find by uri foreach (NwdUriProcessEntry pe in currentlyProcessing) { if (res[pe.URI].Count > 0) { pe.DeviceObject = res[pe.URI].First(); } pe.Processed = true; processed.Add(pe); } again = NineWorldsDeep.UI.Prompt.Confirm("Processing took " + watch.Elapsed.ToString() + " milliseconds to complete. Process more entries?"); } Display.Grid(processed.Count() + " processed / " + unprocessedDeletions.Count() + " unprocessed", processed); if (NineWorldsDeep.UI.Prompt.Confirm("Delete all processed and found files?")) { int deletionCount = 0; foreach (NwdUriProcessEntry pe in processed) { if (pe.FoundOnDevice) { NwdPortableDeviceObject pdo = pe.DeviceObject; if (pdo is NwdPortableDeviceFile) { try { NwdPortableDeviceFile pdf = (NwdPortableDeviceFile)pdo; device.DeleteFile(pdf); deletionCount++; MessageBox.Show(deletionCount + " files deleted"); } catch(Exception ex) { Display.Exception(ex); } } } } if (unprocessedDeletions.Count < 1 && toBeRemoved != null) { string confirmMsg = "No more unprocessed entries for [" + toBeRemoved.Name + "] delete file?"; if (NineWorldsDeep.UI.Prompt.Confirm(confirmMsg)) { device.DeleteFile(toBeRemoved); MessageBox.Show("[" + toBeRemoved.Name + "] deleted."); unprocessedDeletions = null; toBeRemoved = null; } } } } } } else { MessageBox.Show("no devices found."); } }
public void DeleteFile(NwdPortableDeviceFile file) { Connect(); IPortableDeviceContent content; this._device.Content(out content); var variant = new tag_inner_PROPVARIANT(); StringToPropVariant(file.Id, out variant); IPortableDevicePropVariantCollection objectIds = new PortableDeviceTypesLib.PortableDevicePropVariantCollection() as IPortableDevicePropVariantCollection; objectIds.Add(variant); content.Delete(0, objectIds, null); Disconnect(); }