/// <summary> /// Tries to start running the prepared RFileSystemWatcher. /// If this fails, blacklists the drive and calls StopWatcher, /// which cleans up everything related to this drive. /// </summary> /// <param name="w">RFileSystemWatcher to start.</param> private static void StartWatcher(RemovableFileSystemWatcher w) { Exception e = null; try { if (!w.WasDisposed) { w.EnableRaisingEvents = true; } } catch (IOException ex) //drive unavailable { e = ex; } catch (ApplicationException ex) //drive is incompatible { e = ex; } if (e != null) //something bad happened { var dName = w.Path; Debug.WriteLine("DriveManager: cannot inistantiate watcher for {0}, reason:\r\n{1}", dName, e.Message); BlackList.Add(dName); StopWatcher(dName); } }
/// <summary> /// The background thread that watches the drives in the system, querying them every 5 seconds /// </summary> private static void Worker() { begin: lock (DriveNames) //To ensure no InvalidOperationException occurs in GetDriveLabel() { //Also syncs handler above _drives = DriveInfo.GetDrives(); //Have some drives been removed? for (int i = DriveNames.Count - 1; i >= 0; i--) { var dName = DriveNames[i]; if (_drives.All(d => d.Name != dName)) //drive removed { StopWatcher(dName); //stop the COM watcher and remove drive from collection } } //Has blacklisted drive been removed? BlackList.RemoveAll(bl => _drives.All(d => d.Name != bl)); //Have some drives been addded? foreach (var driveInfo in _drives) { var dName = driveInfo.Name; if (DriveNames.All(d => d != dName)) //drive added { if (IsDriveValid(driveInfo)) { RemovableFileSystemWatcher w; try { w = new RemovableFileSystemWatcher(dName, _reportingHandle); } catch (ArgumentException ex) { Debug.WriteLine("DriveManager: cannot inistantiate watcher for {0}, reason:\r\n{1}", dName, ex.Message); BlackList.Add(dName); continue; } DriveNames.Add(dName); //Add drive to collection var fn = GetFormattedDriveLabel(dName); //override deadlock Util.Send(() => //Add drive to UI _drivesRoot.Items.Add(new PowerItem { Argument = dName, AutoExpand = true, IsFolder = true, Parent = _drivesRoot, NonCachedIcon = true, FriendlyName = fn })); //Add drive watcher w.Created += PushEvent; w.Deleted += PushEvent; w.Changed += PushEvent; w.Renamed += PushEvent; w.IncludeSubdirectories = true; Watchers.Add(w); if (BtnStck.IsInstantited) { StartWatcher(w); } else { BtnStck.Instanciated += (sender, args) => StartWatcher(w); } } } } } if (!Util.MainDisp.HasShutdownStarted) { Thread.Sleep(5000); goto begin; //just don't want unneeded code nesting here, anyway IL will be same. } DriveNames.ForEach(StopWatcher); }