private TreeNode addNodesForDirectory(DirectoryInfo dir, TreeNode root) { TreeNodeDirTag tag = new TreeNodeDirTag(dir); TreeNode tn = new TreeNode() { Tag = tag, Text = dir.Name, Name = dir.Name }; DirectoryInfo[] subdirs = dir.GetDirectories(); for (int i = 0; i < subdirs.Length; ++i) { addNodesForDirectory(subdirs[i], tn); } if (root != null) { root.Nodes.Add(tn); } return(tn); }
/// <summary> /// "Sorts" a directory for head units/other embedded devices to read in order that otherwise wouldn't. /// /// This is done by simply moving a folder/file to a temporary directory, and then back to its original location, /// in the order specified by TreeNode. /// </summary> /// <param name="node">node to sort</param> private void sortTreeNodeDirectories(TreeNode node) { TreeNodeDirTag tag = (TreeNodeDirTag)node.Tag; DirectoryInfo dir = tag.dir; bool isRootDir = node.Parent == null; string dirFullName; try { dirFullName = dir.FullName; } catch { this.writeToLog("WARNING: Unable to read full name of input directory. Wat? Skipping..."); return; } if (isRootDir) { this.progressBar.Value = 0; Application.DoEvents(); } float progressBarInc = 100 / node.Nodes.Count; // Temp folder is not created until absolutely necessary. DirectoryInfo temp = null; bool haveHitChangedTag = false; for (int i = 0; i < node.Nodes.Count; ++i) { if (node.Nodes[i].Tag is TreeNodeDirTag subTag) { DirectoryInfo subdir = subTag.dir; try { if (isRootDir) { this.writeToLog(Environment.NewLine + "Sorting Folder: " + subdir.Name); } else { this.writeToLog("Sorting Folder: " + Path.Combine(subdir.Parent.Name, subdir.Name)); } } catch { this.writeToLog("WARNING: Failed to log folder being sorted? Attempting to continue..."); } // In order to avoid clogging up the FAT structures and require a clean-up/format, // skip ahead until we hit a tag that has changed/been sorted. This avoids unnecessary // moves completely. NOTE: this is after the logging so users aren't confused. if (subTag.wasMoved) { haveHitChangedTag = true; } if (!haveHitChangedTag) { goto loopSkipAhead; } // The first folder can always be skipped, doing all the others // after it will effectively move it to first in the order. if (i == 0) { subTag.wasMoved = false; goto loopSkipAhead; } if (temp == null) { try { temp = Util.getTempDir(dir); temp.Create(); } catch { this.writeToLog("WARNING: Unable to create temp directory in \"" + dirFullName + "\". Skipping..."); goto loopSkipAhead; } } // Further avoiding clogging up the FAT structures, we use // short folder names for moves. This avoids LFN entries. DirectoryInfo tempSubTemp = null; string origFolderName = null; try { tempSubTemp = Util.getTempDir(temp); // will be created by MoveTo origFolderName = subdir.Name; } catch { this.writeToLog("WARNING: Failed to create a proper temp directory. Attempting to continue..."); } try { if (tempSubTemp != null && origFolderName != null) { subdir.MoveTo(Path.Combine(temp.FullName, tempSubTemp.Name)); } else { subdir.MoveTo(Path.Combine(temp.FullName, subdir.Name)); } } catch { this.writeToLog("WARNING: Failed to move \"" + subdir.Name + "\" to temporary directory! Skipping..."); goto loopSkipAhead; } try { if (tempSubTemp != null && origFolderName != null) { subdir.MoveTo(Path.Combine(temp.Parent.FullName, origFolderName)); } else { subdir.MoveTo(Path.Combine(temp.Parent.FullName, subdir.Name)); } } catch { this.writeToLog("MAJOR ERROR! Failed to move \"" + subdir.Name + "\" back from temporary directory! You may need to find/fix this or restore a backup!"); goto loopSkipAhead; } // Might as well un-set that the tag was moved, since it just got sorted... subTag.wasMoved = false; loopSkipAhead: try { if (node.Nodes[i].Nodes.Count > 0) { sortTreeNodeDirectories(node.Nodes[i]); } } catch (Exception e) { this.writeToLog("UNEXPECTED EXCEPTION OCCURRED! " + e.GetType().ToString() + ": " + e.Message); this.writeToLog("ERROR: Major unhandled exception. Please copy this log and file a bug report."); this.writeToLog("We will attempt to continue in hopes that this is benign."); } } else { this.writeToLog("Odd error has occurred, Node Tag is not a DirectoryInfo?"); } // TODO: Fix progress bar to increment smoothly as sub-folders are progressed through as well, not just main folders. if (isRootDir) { this.progressBar.Value = (int)(progressBarInc * i); Application.DoEvents(); } } if (temp != null) { try { temp.Delete(); } catch (DirectoryNotFoundException) { this.writeToLog("WARNING: Unable to remove temp directory \"" + temp.FullName + "\" because it no longer exists. Skipping..."); } catch { this.writeToLog("WARNING: Unable to remove temp directory \"" + temp.FullName + "\". Skipping..."); } } if (isRootDir) { this.progressBar.Value = 100; Application.DoEvents(); } }