public LocalFilesystemEntry IterateDirectory(DirectoryInfo directoryInfo) { var directoryRelativePath = GetRelativePath(LocalDirectoryPath, directoryInfo.FullName, true); LocalFilesystemEntry directory = new LocalFilesystemEntry(this, directoryRelativePath, true); foreach (var childDirectoryInfo in directoryInfo.EnumerateDirectories()) { var childDirectory = IterateDirectory(childDirectoryInfo); directory.Items.Add(childDirectory); } foreach (var childFileInfo in directoryInfo.EnumerateFiles()) { var childFileRelativePath = GetRelativePath(LocalDirectoryPath, childFileInfo.FullName, false); var childFile = new LocalFilesystemEntry(this, childFileRelativePath, false); { var filepath_test = Path.Combine(LocalDirectoryPath, childFile.FullPath); if (!File.Exists(filepath_test)) { throw new Exception("Invalid filepaths"); } } directory.Items.Add(childFile); Files.Add(childFile); } Folders.Add(directory); FolderLookup[directory.FullPath] = directory; return(directory); }
private void Watcher_Event_Ext(object sender, FileSystemEventArgs e, bool isDirectory) { RenamedEventArgs renamedEventArgs = e as RenamedEventArgs; string FullPath = e.ChangeType == WatcherChangeTypes.Renamed ? renamedEventArgs.OldFullPath : e.FullPath; string NewFullPath = e.ChangeType == WatcherChangeTypes.Renamed ? renamedEventArgs.FullPath : null; switch (e.ChangeType) { case WatcherChangeTypes.Created: case WatcherChangeTypes.Changed: FileAttributes attr = File.GetAttributes(FullPath); isDirectory = (attr & FileAttributes.Directory) == FileAttributes.Directory; break; case WatcherChangeTypes.Renamed: case WatcherChangeTypes.Deleted: // rely on event break; default: throw new NotImplementedException(); } var directory = new DirectoryInfo(Path.GetDirectoryName(FullPath)).FullName; var relativeDirectory = GetRelativePath(LocalDirectoryPath, directory, true); var relativePath = GetRelativePath(LocalDirectoryPath, FullPath, isDirectory); if (relativeDirectory.EndsWith("\\")) { relativeDirectory = relativeDirectory.Substring(0, relativeDirectory.Length - 1); } if (relativePath.EndsWith("\\")) { relativePath = relativePath.Substring(0, relativePath.Length - 1); } // useful helper, can be included or discarded var name = Path.GetFileName(e.FullPath); var filesystemEntry = new LocalFilesystemEntry(this, relativePath, isDirectory); MainWindow.PrimaryWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(delegate() { lock (this) { switch (e.ChangeType) { case WatcherChangeTypes.Created: if (!FolderLookup.ContainsKey(relativeDirectory)) { var lastFolder = FolderLookup[""]; var currentFolderPath = ""; var folderNames = relativeDirectory.Split('\\'); foreach (var folderName in folderNames) { if (string.IsNullOrWhiteSpace(currentFolderPath)) { currentFolderPath = folderName; } else { currentFolderPath += $"\\{folderName}"; } if (FolderLookup.ContainsKey(currentFolderPath)) { lastFolder = FolderLookup[currentFolderPath]; } else { IFilesystemEntry entry = new LocalFilesystemEntry(this, currentFolderPath, true); lastFolder.Items.Add(entry); FolderLookup[entry.FullPath] = entry; lastFolder = entry; } } if (!FolderLookup.ContainsKey(relativeDirectory)) { throw new Exception("The f**k?"); } } if (FolderLookup.ContainsKey(relativeDirectory)) { var folder = FolderLookup[relativeDirectory]; if (isDirectory) { FolderLookup[filesystemEntry.FullPath] = filesystemEntry; Folders.Add(filesystemEntry); CreateWatcher(); } else { Files.Add(filesystemEntry); } folder.Items.Add(filesystemEntry); } else { throw new Exception("Folder should always be found!"); } break; case WatcherChangeTypes.Changed: break; case WatcherChangeTypes.Renamed: var newRelativePath = GetRelativePath(LocalDirectoryPath, NewFullPath, isDirectory); var newFilesystemEntry = new LocalFilesystemEntry(this, newRelativePath, isDirectory); if (FolderLookup.ContainsKey(relativeDirectory)) { var existingParentFolder = FolderLookup[relativeDirectory]; if (isDirectory) { var existingFolder = FolderLookup[filesystemEntry.FullPath]; FolderLookup.Remove(filesystemEntry.FullPath); existingFolder.Name = newFilesystemEntry.Name; FolderLookup[existingFolder.FullPath] = existingFolder; } else { IFilesystemEntry existingFile = null; foreach (var entry in existingParentFolder.Items) { if (entry.Name == filesystemEntry.Name) { existingFile = entry; } } if (existingFile == null) { throw new Exception("File should always be found!"); } } } else { throw new Exception("Folder should always be found!"); } break; case WatcherChangeTypes.Deleted: if (FolderLookup.ContainsKey(relativeDirectory)) { var existingParentFolder = FolderLookup[relativeDirectory]; if (isDirectory) { var existingFolder = FolderLookup[filesystemEntry.FullPath]; // TODO: just lookup parent, its faster! foreach (var folder in Folders) { folder.Items.Remove(existingFolder); } Folders.Remove(existingFolder); FolderLookup.Remove(filesystemEntry.FullPath); } else { IFilesystemEntry existingFile = null; foreach (var entry in existingParentFolder.Items) { if (entry.Name == filesystemEntry.Name) { existingFile = entry; } } if (existingFile != null) { existingParentFolder.Items.Remove(existingFile); } else { //TODO: figure out why sometimes files aren't found //throw new Exception("File should always be found!"); } } } else { throw new Exception("Folder should always be found!"); } break; case WatcherChangeTypes.All: break; } } })); }