PageRenderTime 64ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 2ms

/verve patch/base/Applications/BetterExplorer/BExplorer/BetterExplorer/MainWindow.xaml.cs

https://bitbucket.org/jdm7dvmoore/msft-research-verve
C# | 4158 lines | 3239 code | 628 blank | 291 comment | 747 complexity | 4806bfa8d44f4dae5cca83557fa289ee MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. // --------------------------------------------------------------------------------------------------------------------
  2. // <copyright file="MainWindow.xaml.cs" company="Gainedge ORG">
  3. // Better Explorer (c)2016
  4. // </copyright>
  5. // <summary>
  6. // Interaction logic for MainWindow.xaml
  7. // </summary>
  8. // --------------------------------------------------------------------------------------------------------------------
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Collections.Specialized;
  12. using System.ComponentModel;
  13. using System.Diagnostics;
  14. using System.Drawing;
  15. using System.Drawing.Imaging;
  16. using System.IO;
  17. using System.Linq;
  18. using System.Net;
  19. using System.Reflection;
  20. using System.Runtime.InteropServices;
  21. using System.ServiceModel;
  22. using System.Text;
  23. using System.Threading;
  24. using System.Threading.Tasks;
  25. using System.Windows;
  26. using System.Windows.Controls;
  27. using System.Windows.Controls.Primitives;
  28. using System.Windows.Input;
  29. using System.Windows.Interop;
  30. using System.Windows.Media;
  31. using System.Windows.Media.Imaging;
  32. using System.Windows.Shell;
  33. using System.Windows.Threading;
  34. using System.Xml;
  35. using System.Xml.Linq;
  36. using BEHelper;
  37. using BetterExplorer.UsbEject;
  38. using BetterExplorerControls;
  39. using BExplorer.Shell;
  40. using BExplorer.Shell._Plugin_Interfaces;
  41. using BExplorer.Shell.CommonFileDialogs;
  42. using BExplorer.Shell.DropTargetHelper;
  43. using BExplorer.Shell.Interop;
  44. using Fluent;
  45. using LTR.IO.ImDisk;
  46. using Microsoft.Win32;
  47. using Settings;
  48. using SevenZip;
  49. using Shell32;
  50. using TaskDialogInterop;
  51. using wyDay.Controls;
  52. using Clipboards = System.Windows.Forms.Clipboard;
  53. using ContextMenu = Fluent.ContextMenu;
  54. using Image = System.Windows.Controls.Image;
  55. using MenuItem = Fluent.MenuItem;
  56. using WIN = System.Windows;
  57. namespace BetterExplorer {
  58. /// <summary>
  59. /// Interaction logic for MainWindow.xaml
  60. /// </summary>
  61. public partial class MainWindow : Fluent.RibbonWindow {
  62. #region DLLImports
  63. [DllImport("user32.dll")]
  64. [return: MarshalAs(UnmanagedType.Bool)]
  65. internal static extern bool GetCursorPos(ref BExplorer.Shell.DataObject.Win32Point pt);
  66. //[DllImport("user32.dll", SetLastError = true)]
  67. //private static extern int RegisterHotKey(IntPtr hwnd, int id, int fsModifiers, int vk);
  68. //[DllImport("user32.dll", SetLastError = true)]
  69. //private static extern int UnregisterHotKey(IntPtr hwnd, int id);
  70. [DllImport("winmm.dll")]
  71. static extern Int32 mciSendString(String command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback);
  72. #endregion
  73. #region Private Members
  74. private bool _IsCalledFromLoading, isOnLoad;
  75. private MenuItem misa, misd, misag, misdg;
  76. private ShellTreeViewEx ShellTree = new ShellTreeViewEx();
  77. private ShellView _ShellListView = new ShellView();
  78. private bool IsNeedEnsureVisible;
  79. private ClipboardMonitor cbm = new ClipboardMonitor();
  80. private ContextMenu _CMHistory = new ContextMenu();
  81. private WIN.Shell.JumpList AppJL = new WIN.Shell.JumpList();
  82. //private List<string> Archives = new List<string>(new[] { ".rar", ".zip", ".7z", ".tar", ".gz", ".xz", ".bz2" });
  83. private List<string> Images = new List<string>(new[] { ".jpg", ".jpeg", ".png", ".bmp", ".gif", ".wmf" });
  84. private string SelectedArchive = "";
  85. private bool KeepBackstageOpen = false;
  86. string sessionid = DateTime.UtcNow.ToFileTimeUtc().ToString();
  87. string logdir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\BExplorer\\ActionLog\\";
  88. WIN.Forms.Timer updateCheckTimer = new WIN.Forms.Timer();
  89. Double CommandPromptWinHeight;
  90. //List<LVItemColor> LVItemsColor { get; set; }
  91. ContextMenu chcm;
  92. WIN.Forms.Timer focusTimer = new WIN.Forms.Timer() { Interval = 500 };
  93. private WIN.Forms.Timer _ProgressTimer = new WIN.Forms.Timer() { Interval = 1000, Enabled = false };
  94. private string _DBPath = Path.Combine(KnownFolders.RoamingAppData.ParsingName, @"BExplorer\Settings.sqlite");
  95. private IntPtr Handle;
  96. private ObservableCollectionEx<LVItemColor> LVItemsColorCol { get; set; }
  97. public Dictionary<String, Dictionary<IListItemEx, List<string>>> Badges { get; set; }
  98. #endregion
  99. public bool IsMultipleWindowsOpened { get; set; }
  100. #region Events
  101. private void btnAbout_Click(object sender, RoutedEventArgs e) => new fmAbout(this).ShowDialog();
  102. private void btnBugtracker_Click(object sender, RoutedEventArgs e) => Process.Start("http://bugs.gainedge.org/public/betterexplorer");
  103. private void TheRibbon_CustomizeQuickAccessToolbar(object sender, EventArgs e) => CustomizeQAT.Open(this, TheRibbon);
  104. private void btnConsolePane_Click(object sender, RoutedEventArgs e) {
  105. Settings.BESettings.IsConsoleShown = btnConsolePane.IsChecked.Value;
  106. Settings.BESettings.SaveSettings();
  107. if (btnConsolePane.IsChecked.Value) {
  108. rCommandPrompt.Height = new GridLength(this.CommandPromptWinHeight);
  109. rCommandPrompt.MinHeight = 100;
  110. spCommandPrompt.Height = GridLength.Auto;
  111. if (!ctrlConsole.IsProcessRunning)
  112. ctrlConsole.ChangeFolder(_ShellListView.CurrentFolder.ParsingName, _ShellListView.CurrentFolder.IsFileSystem);
  113. } else {
  114. rCommandPrompt.MinHeight = 0;
  115. rCommandPrompt.Height = new GridLength(0);
  116. spCommandPrompt.Height = new GridLength(0);
  117. ctrlConsole.StopProcess();
  118. }
  119. }
  120. private void backstage_IsOpenChanged(object sender, DependencyPropertyChangedEventArgs e) {
  121. if ((Boolean)e.NewValue) {
  122. this._ShellListView.IsFocusAllowed = false;
  123. this.backstage.Focus();
  124. } else {
  125. this._ShellListView.IsFocusAllowed = true;
  126. }
  127. this.autoUpdater.Visibility = Visibility.Visible;
  128. this.autoUpdater.UpdateLayout();
  129. if (this.KeepBackstageOpen) {
  130. this.backstage.IsOpen = true;
  131. this.KeepBackstageOpen = false;
  132. }
  133. }
  134. /// <summary>
  135. /// Loads initial position of the main window
  136. /// </summary>
  137. private void LoadInitialWindowPositionAndState() {
  138. this.Width = BESettings.LastWindowWidth;
  139. this.Height = BESettings.LastWindowHeight;
  140. var location = new System.Drawing.Point();
  141. try {
  142. location = new System.Drawing.Point((int)BESettings.LastWindowPosLeft, (int)BESettings.LastWindowPosTop);
  143. } catch { }
  144. this.Left = location.X;
  145. this.Top = location.Y;
  146. switch (BESettings.LastWindowState) {
  147. case 2:
  148. this.WindowState = WindowState.Maximized;
  149. break;
  150. case 1:
  151. this.WindowState = WindowState.Minimized;
  152. break;
  153. case 0:
  154. this.WindowState = WindowState.Normal;
  155. break;
  156. default:
  157. this.WindowState = WindowState.Maximized;
  158. break;
  159. }
  160. this.chkRibbonMinimizedGlass.IsChecked = BESettings.IsGlassOnRibonMinimized;
  161. this.TheRibbon.IsMinimized = BESettings.IsRibonMinimized;
  162. //CommandPrompt window size
  163. this.CommandPromptWinHeight = BESettings.CmdWinHeight;
  164. this.rCommandPrompt.Height = new GridLength(this.CommandPromptWinHeight);
  165. if (BESettings.IsConsoleShown) {
  166. this.rCommandPrompt.MinHeight = 100;
  167. this.rCommandPrompt.Height = new GridLength(this.CommandPromptWinHeight);
  168. this.spCommandPrompt.Height = GridLength.Auto;
  169. } else {
  170. this.rCommandPrompt.MinHeight = 0;
  171. this.rCommandPrompt.Height = new GridLength(0);
  172. this.spCommandPrompt.Height = new GridLength(0);
  173. }
  174. }
  175. private void LoadColorCodesFromFile() {
  176. Task.Run(() => {
  177. var itemColorSettingsLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"BExplorer\itemcolors.cfg");
  178. if (File.Exists(itemColorSettingsLocation)) {
  179. var docs = XDocument.Load(itemColorSettingsLocation);
  180. docs.Root.Elements("ItemColorRow")
  181. .Select(
  182. element =>
  183. new LVItemColor(
  184. element.Elements().ToArray()[0].Value,
  185. WIN.Media.Color.FromArgb(
  186. BitConverter.GetBytes(Convert.ToInt32(element.Elements().ToArray()[1].Value))[0],
  187. BitConverter.GetBytes(Convert.ToInt32(element.Elements().ToArray()[1].Value))[1],
  188. BitConverter.GetBytes(Convert.ToInt32(element.Elements().ToArray()[1].Value))[2],
  189. BitConverter.GetBytes(Convert.ToInt32(element.Elements().ToArray()[1].Value))[3])))
  190. .ToList().ForEach(e => this.LVItemsColorCol.Add(e));
  191. }
  192. });
  193. }
  194. private void RibbonWindow_Initialized(object sender, EventArgs e) {
  195. this.LoadInitialWindowPositionAndState();
  196. this.LoadColorCodesFromFile();
  197. AppCommands.RoutedNewTab.InputGestures.Add(new KeyGesture(Key.T, ModifierKeys.Control));
  198. AppCommands.RoutedEnterInBreadCrumbCombo.InputGestures.Add(new KeyGesture(Key.E, ModifierKeys.Alt));
  199. AppCommands.RoutedChangeTab.InputGestures.Add(new KeyGesture(Key.Tab, ModifierKeys.Control));
  200. AppCommands.RoutedCloseTab.InputGestures.Add(new KeyGesture(Key.W, ModifierKeys.Control));
  201. AppCommands.RoutedNavigateBack.InputGestures.Add(new KeyGesture(Key.Left, ModifierKeys.Alt));
  202. AppCommands.RoutedNavigateFF.InputGestures.Add(new KeyGesture(Key.Right, ModifierKeys.Alt));
  203. AppCommands.RoutedNavigateUp.InputGestures.Add(new KeyGesture(Key.Up, ModifierKeys.Alt));
  204. AppCommands.RoutedGotoSearch.InputGestures.Add(new KeyGesture(Key.F, ModifierKeys.Control));
  205. }
  206. #region ViewEnumerationComplete
  207. /// <summary>
  208. /// Sets up btnSort and btnGroup so they have the correct items after navigating
  209. /// </summary>
  210. private void SetSortingAndGroupingButtons() {
  211. btnSort.Items.Clear();
  212. btnGroup.Items.Clear();
  213. try {
  214. foreach (Collumns item in _ShellListView.Collumns.Where(x => x != null)) {
  215. var lastSortedColumn = _ShellListView.Collumns.FirstOrDefault(w => w.ID == this._ShellListView.LastSortedColumnId);
  216. if (lastSortedColumn != null) {
  217. var IsChecked1 = (item.pkey.fmtid == lastSortedColumn.pkey.fmtid) && (item.pkey.pid == lastSortedColumn.pkey.pid);
  218. btnSort.Items.Add(Utilities.Build_MenuItem(item.Name, item, checkable: true, isChecked: IsChecked1, GroupName: "GR2", onClick: mi_Click));
  219. }
  220. var IsCheckable2 = _ShellListView.LastGroupCollumn != null && (item.pkey.fmtid == _ShellListView.LastGroupCollumn.pkey.fmtid) && (item.pkey.pid == _ShellListView.LastGroupCollumn.pkey.pid);
  221. btnGroup.Items.Add(Utilities.Build_MenuItem(item.Name, item, checkable: true, isChecked: IsCheckable2, GroupName: "GR3", onClick: mig_Click));
  222. }
  223. } catch (Exception ex) {
  224. //FIXME: I disable this message because of strange null after filter
  225. MessageBox.Show("BetterExplorer had an issue loading the visible columns for the current view. You might not be able to sort or group items.", ex.ToString(), MessageBoxButton.OK, MessageBoxImage.Error);
  226. }
  227. btnSort.Items.Add(new Separator() { Focusable = false });
  228. misa = Utilities.Build_MenuItem(FindResource("miAscending"), checkable: true, GroupName: "GR1", onClick: misa_Click);
  229. misd = Utilities.Build_MenuItem(FindResource("miDescending"), checkable: true, GroupName: "GR1", onClick: misd_Click);
  230. if (this._ShellListView.LastSortOrder == WIN.Forms.SortOrder.Ascending)
  231. misa.IsChecked = true;
  232. else
  233. misd.IsChecked = true;
  234. btnSort.Items.Add(misa);
  235. btnSort.Items.Add(misd);
  236. btnGroup.Items.Add(Utilities.Build_MenuItem("(none)", GroupName: "GR3", checkable: true, isChecked: _ShellListView.LastGroupCollumn == null, onClick: misng_Click));
  237. btnGroup.Items.Add(new Separator());
  238. misag = Utilities.Build_MenuItem(FindResource("miAscending"), checkable: true, GroupName: "GR4", onClick: misag_Click);
  239. misdg = Utilities.Build_MenuItem(FindResource("miDescending"), checkable: true, GroupName: "GR4", onClick: misag_Click);
  240. if (this._ShellListView.LastGroupOrder == WIN.Forms.SortOrder.Ascending)
  241. misag.IsChecked = true;
  242. else
  243. misdg.IsChecked = true;
  244. btnGroup.Items.Add(misag);
  245. btnGroup.Items.Add(misdg);
  246. }
  247. void misag_Click(object sender, RoutedEventArgs e) {
  248. this._ShellListView.SetGroupOrder();
  249. }
  250. private void SetupColumnsButton() {
  251. var allAvailColls = this._ShellListView.AllAvailableColumns.Values.ToList();
  252. btnMoreColls.Items.Clear();
  253. chcm.Items.Clear();
  254. for (int j = 1; j < 10; j++) {
  255. //TODO: Try to remove this Try Catch!!
  256. try {
  257. var IsChecked = _ShellListView.Collumns.Any(col => col.pkey.fmtid == allAvailColls[j].pkey.fmtid && col.pkey.pid == allAvailColls[j].pkey.pid);
  258. btnMoreColls.Items.Add(Utilities.Build_MenuItem(allAvailColls[j].Name, allAvailColls[j], checkable: true, onClick: mic_Click, isChecked: IsChecked));
  259. chcm.Items.Add(Utilities.Build_MenuItem(allAvailColls[j].Name, allAvailColls[j], checkable: true, onClick: mic_Click, isChecked: IsChecked));
  260. } catch (Exception) {
  261. }
  262. }
  263. int ItemsCount = _ShellListView.Items.Count;
  264. sbiItemsCount.Visibility = ItemsCount == 0 ? Visibility.Collapsed : Visibility.Visible;
  265. sbiItemsCount.Content = ItemsCount == 1 ? "1 item" : ItemsCount + " items";
  266. sbiSelItemsCount.Visibility = _ShellListView.GetSelectedCount() == 0 ? Visibility.Collapsed : Visibility.Visible;
  267. spSelItems.Visibility = sbiSelItemsCount.Visibility;
  268. btnMoreColls.Items.Add(new Separator());
  269. btnMoreColls.Items.Add(Utilities.Build_MenuItem(FindResource("btnMoreColCP"), allAvailColls, onClick: micm_Click));
  270. btnMoreColls.Tag = allAvailColls;
  271. chcm.Items.Add(new Separator());
  272. chcm.Items.Add(Utilities.Build_MenuItem(FindResource("btnMoreColCP"), allAvailColls, onClick: micm_Click));
  273. }
  274. #endregion
  275. void misd_Click(object sender, RoutedEventArgs e) {
  276. foreach (var item in btnSort.Items.OfType<MenuItem>().Where(item => item.IsChecked && item != (sender as MenuItem))) {
  277. _ShellListView.SetSortCollumn(true, (Collumns)item.Tag, WIN.Forms.SortOrder.Descending);
  278. }
  279. }
  280. void misa_Click(object sender, RoutedEventArgs e) {
  281. foreach (var item in btnSort.Items.OfType<MenuItem>().Where(item => item.IsChecked && item != (sender as MenuItem))) {
  282. _ShellListView.SetSortCollumn(true, (Collumns)item.Tag, WIN.Forms.SortOrder.Ascending);
  283. }
  284. }
  285. void micm_Click(object sender, RoutedEventArgs e) {
  286. var fMoreCollumns = new MoreColumns();
  287. fMoreCollumns.PopulateAvailableColumns((List<Collumns>)(sender as FrameworkElement).Tag, this._ShellListView, this.PointToScreen(Mouse.GetPosition(this)));
  288. }
  289. void mic_Click(object sender, RoutedEventArgs e) {
  290. var mi = (sender as MenuItem);
  291. Collumns col = (Collumns)mi.Tag;
  292. _ShellListView.SetColInView(col, !mi.IsChecked);
  293. }
  294. void miItem_Click(object sender, RoutedEventArgs e) {
  295. MenuItem mi = sender as MenuItem;
  296. ShellItem SaveLoc = mi.Tag as ShellItem;
  297. if (_ShellListView.CurrentFolder.ParsingName.Contains(KnownFolders.Libraries.ParsingName) && _ShellListView.CurrentFolder.ParsingName.EndsWith("library-ms")) {
  298. var lib = ShellLibrary.Load(Path.GetFileNameWithoutExtension(_ShellListView.CurrentFolder.ParsingName), false);
  299. lib.DefaultSaveFolder = SaveLoc.ParsingName;
  300. lib.Close();
  301. } else if (_ShellListView.GetFirstSelectedItem().ParsingName.Contains(KnownFolders.Libraries.ParsingName)) {
  302. var lib = ShellLibrary.Load(Path.GetFileNameWithoutExtension(_ShellListView.GetFirstSelectedItem().ParsingName), false);
  303. lib.DefaultSaveFolder = SaveLoc.ParsingName;
  304. lib.Close();
  305. }
  306. }
  307. void LinksFolderWarcher_Renamed(object sender, RenamedEventArgs e) {
  308. Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(
  309. () => btnFavorites.Items.OfType<MenuItem>().First(x => (x.Tag as ShellItem).ParsingName == e.OldFullPath).Header = Path.GetFileNameWithoutExtension(e.Name)));
  310. }
  311. void LinksFolderWarcher_Deleted(object sender, FileSystemEventArgs e) {
  312. Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(
  313. () => btnFavorites.Items.Remove(btnFavorites.Items.OfType<MenuItem>().First(item => item.Header.ToString() == Path.GetFileNameWithoutExtension(e.Name)))));
  314. }
  315. void LinksFolderWarcher_Created(object sender, FileSystemEventArgs e) {
  316. Dispatcher.BeginInvoke(DispatcherPriority.Normal,
  317. (Action)(() => {
  318. if (Path.GetExtension(e.FullPath).ToLowerInvariant() == ".lnk") {
  319. var so = new ShellItem(e.FullPath);
  320. so.Thumbnail.FormatOption = ShellThumbnailFormatOption.IconOnly;
  321. so.Thumbnail.CurrentSize = new WIN.Size(16, 16);
  322. ImageSource icon = so.Thumbnail.BitmapSource;
  323. btnFavorites.Items.Add(Utilities.Build_MenuItem(so.DisplayName, so, icon, onClick: mif_Click));
  324. }
  325. }));
  326. }
  327. /// <summary>
  328. /// Sets up each ribbon tab after select or navigate in ShellListView
  329. /// </summary>
  330. /// <param name="selectedItemsCount">The number of items selected</param>
  331. /// <param name="selectedItem">The last selected item</param>
  332. /// <remarks>
  333. /// Only used in SetupUIOnSelectOrNavigate
  334. /// </remarks>
  335. private void SetUpRibbonTabsVisibilityOnSelectOrNavigate(int selectedItemsCount, IListItemEx selectedItem) {
  336. #region Search Contextual Tab
  337. ctgSearch.Visibility = BooleanToVisibiliy(_ShellListView.CurrentFolder.IsSearchFolder);
  338. if (ctgSearch.Visibility == Visibility.Visible && !_ShellListView.CurrentFolder.IsSearchFolder) {
  339. ctgSearch.Visibility = Visibility.Collapsed;
  340. TheRibbon.SelectedTabItem = HomeTab;
  341. }
  342. #endregion
  343. #region Folder Tools Context Tab
  344. ctgFolderTools.Visibility = BooleanToVisibiliy((selectedItemsCount == 1 && selectedItem.IsFolder && selectedItem.IsFileSystem && !selectedItem.IsDrive && !selectedItem.IsNetworkPath));
  345. if (BESettings.AutoSwitchFolderTools && ctgFolderTools.Visibility == Visibility.Visible) {
  346. TheRibbon.SelectedTabItem = ctgFolderTools.Items[0];
  347. }
  348. #endregion
  349. #region Drive Contextual Tab
  350. ctgDrive.Visibility = BooleanToVisibiliy(_ShellListView.CurrentFolder.IsDrive || (selectedItemsCount == 1 && (selectedItem.IsDrive || (selectedItem.Parent != null && selectedItem.Parent.IsDrive))));
  351. if (BESettings.AutoSwitchDriveTools && ctgDrive.Visibility == Visibility.Visible && selectedItemsCount == 1 && selectedItem.IsDrive) {
  352. TheRibbon.SelectedTabItem = ctgDrive.Items[0];
  353. }
  354. #endregion
  355. #region Library Context Tab
  356. ctgLibraries.Visibility = BooleanToVisibiliy((selectedItemsCount == 1 && _ShellListView.CurrentFolder.ParsingName.Equals(KnownFolders.Libraries.ParsingName)) || (selectedItemsCount == 1 && selectedItem.Parent != null && selectedItem.Parent.ParsingName.Equals(KnownFolders.Libraries.ParsingName)));
  357. if (ctgLibraries.Visibility == Visibility.Visible && BESettings.AutoSwitchLibraryTools) {
  358. TheRibbon.SelectedTabItem = ctgLibraries.Items[0];
  359. }
  360. /*
  361. if (ctgLibraries.Visibility == Visibility.Visible && _ShellListView.CurrentFolder.ParsingName.Equals(KnownFolders.Libraries.ParsingName)) {
  362. if (selectedItem != null && selectedItemsCount == 1)
  363. SetupLibrariesTab(ShellLibrary.Load(Path.GetFileNameWithoutExtension(selectedItem.ParsingName), false));
  364. } else if (ctgLibraries.Visibility == Visibility.Visible && _ShellListView.CurrentFolder.Parent.ParsingName.Equals(KnownFolders.Libraries.ParsingName)) {
  365. if (selectedItemsCount == 1)
  366. SetupLibrariesTab(ShellLibrary.Load(Path.GetFileNameWithoutExtension(_ShellListView.CurrentFolder.ParsingName), false));
  367. }
  368. if (selectedItemsCount == 0) {
  369. ctgLibraries.Visibility = Visibility.Collapsed;
  370. }
  371. */
  372. if (selectedItemsCount == 0)
  373. ctgLibraries.Visibility = Visibility.Collapsed;
  374. else if (selectedItemsCount > 1) { } else if (ctgLibraries.Visibility == Visibility.Visible && _ShellListView.CurrentFolder.ParsingName.Equals(KnownFolders.Libraries.ParsingName))
  375. SetupLibrariesTab(ShellLibrary.Load(Path.GetFileNameWithoutExtension(selectedItem.ParsingName), false));
  376. else if (ctgLibraries.Visibility == Visibility.Visible && _ShellListView.CurrentFolder.Parent.ParsingName.Equals(KnownFolders.Libraries.ParsingName))
  377. SetupLibrariesTab(ShellLibrary.Load(Path.GetFileNameWithoutExtension(_ShellListView.CurrentFolder.ParsingName), false));
  378. #endregion
  379. #region Archive Contextual Tab
  380. ctgArchive.Visibility = WIN.Visibility.Collapsed; //TODO: Restore this: BooleanToVisibiliy(selectedItemsCount == 1 && Archives.Contains(Path.GetExtension(selectedItem.ParsingName).ToLowerInvariant()));
  381. if (BESettings.AutoSwitchArchiveTools && ctgArchive.Visibility == Visibility.Visible)
  382. TheRibbon.SelectedTabItem = ctgArchive.Items[0];
  383. #endregion
  384. #region Application Context Tab
  385. ctgExe.Visibility = BooleanToVisibiliy(selectedItemsCount == 1 && !selectedItem.IsFolder && (Path.GetExtension(selectedItem.ParsingName).ToLowerInvariant() == ".exe" || Path.GetExtension(selectedItem.ParsingName).ToLowerInvariant() == ".msi"));
  386. if (BESettings.AutoSwitchApplicationTools && ctgExe.Visibility == Visibility.Visible) {
  387. TheRibbon.SelectedTabItem = ctgExe.Items[0];
  388. }
  389. #endregion
  390. #region Image Context Tab
  391. ctgImage.Visibility = BooleanToVisibiliy(selectedItemsCount == 1 && !selectedItem.IsFolder && Images.Contains(Path.GetExtension(selectedItem.ParsingName).ToLowerInvariant()));
  392. if (ctgImage.Visibility == Visibility.Visible) {
  393. try {
  394. if (new FileInfo(selectedItem.ParsingName).Length != 0) {
  395. using (var cvt = new Bitmap(selectedItem.ParsingName)) {
  396. imgSizeDisplay.WidthData = cvt.Width.ToString();
  397. imgSizeDisplay.HeightData = cvt.Height.ToString();
  398. if (BESettings.AutoSwitchImageTools) TheRibbon.SelectedTabItem = ctgImage.Items[0];
  399. }
  400. }
  401. } catch (Exception) {
  402. MessageBox.Show("Image was invalid");
  403. }
  404. }
  405. #endregion
  406. #region Virtual Disk Context Tab
  407. ctgVirtualDisk.Visibility = BooleanToVisibiliy(selectedItemsCount == 1 && !selectedItem.IsFolder && Path.GetExtension(selectedItem.ParsingName).ToLowerInvariant() == ".iso");
  408. if (BESettings.AutoSwitchVirtualDriveTools && ctgVirtualDisk.Visibility == Visibility.Visible) {
  409. TheRibbon.SelectedTabItem = ctgVirtualDisk.Items[0];
  410. }
  411. #endregion
  412. }
  413. /// <summary>
  414. /// Sets up the status bar
  415. /// </summary>
  416. /// <param name="selectedItemsCount">The number of items currently selected</param>
  417. private void SetUpStatusBarOnSelectOrNavigate(int selectedItemsCount) {
  418. spSelItems.Visibility = BooleanToVisibiliy(selectedItemsCount > 0);
  419. sbiSelItemsCount.Visibility = BooleanToVisibiliy(selectedItemsCount > 0);
  420. if (selectedItemsCount == 1)
  421. sbiSelItemsCount.Content = "1 item selected";
  422. else if (selectedItemsCount > 1)
  423. sbiSelItemsCount.Content = selectedItemsCount.ToString() + " items selected";
  424. }
  425. private void SetUpButtonsStateOnSelectOrNavigate(int selectedItemsCount, IListItemEx selectedItem) {
  426. btnBadges.IsEnabled = selectedItemsCount > 0;
  427. btnCopy.IsEnabled = selectedItemsCount > 0;
  428. btnCopyto.IsEnabled = selectedItemsCount > 0;
  429. btnMoveto.IsEnabled = selectedItemsCount > 0;
  430. btnCut.IsEnabled = selectedItemsCount > 0;
  431. btnDelete.IsEnabled = selectedItem != null && selectedItem.IsFileSystem;
  432. btnRename.IsEnabled = selectedItem != null && (selectedItem.IsFileSystem || (selectedItem.Parent != null && selectedItem.Parent.Equals(KnownFolders.Libraries)));
  433. btnProperties3.IsEnabled = selectedItemsCount > 0;
  434. if (selectedItem != null) {
  435. var rg = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" + Path.GetExtension(selectedItem.ParsingName) + @"\OpenWithProgids");
  436. if (rg == null)
  437. btnEdit.IsEnabled = false;
  438. else {
  439. string filetype = rg.GetValueNames()[0];
  440. rg.Close();
  441. using (var rgtype = Registry.ClassesRoot.OpenSubKey(filetype + @"\shell\edit\command")) {
  442. btnEdit.IsEnabled = !(rgtype == null);
  443. }
  444. }
  445. }
  446. btnSelAll.IsEnabled = selectedItemsCount != _ShellListView.Items.Count;
  447. btnSelNone.IsEnabled = selectedItemsCount > 0;
  448. btnShare.IsEnabled = selectedItemsCount == 1 && selectedItem.IsFolder;
  449. btnAdvancedSecurity.IsEnabled = selectedItemsCount == 1;
  450. btnHideSelItems.IsEnabled = _ShellListView.CurrentFolder.IsFileSystem;
  451. }
  452. private void SetupLibrariesTab(ShellLibrary lib) {
  453. IsFromSelectionOrNavigation = true;
  454. chkPinNav.IsChecked = lib.IsPinnedToNavigationPane;
  455. IsFromSelectionOrNavigation = false;
  456. foreach (ShellItem item in lib) {
  457. item.Thumbnail.FormatOption = ShellThumbnailFormatOption.IconOnly;
  458. item.Thumbnail.CurrentSize = new WIN.Size(16, 16);
  459. btnDefSave.Items.Add(Utilities.Build_MenuItem(item.GetDisplayName(SIGDN.NORMALDISPLAY), item, item.Thumbnail.BitmapSource, GroupName: "GRDS1", checkable: true,
  460. isChecked: item.ParsingName == lib.DefaultSaveFolder, onClick: miItem_Click));
  461. }
  462. btnDefSave.IsEnabled = lib.Count != 0;
  463. lib.Close();
  464. }
  465. /// <summary>
  466. /// Does setup required for the UI when navigation occurs to a new folder
  467. /// </summary>
  468. private void SetupUIOnSelectOrNavigate() {
  469. Dispatcher.BeginInvoke(DispatcherPriority.Background, (ThreadStart)(() => {
  470. btnDefSave.Items.Clear();
  471. var selItemsCount = _ShellListView.GetSelectedCount();
  472. var selectedItem = this._ShellListView.GetFirstSelectedItem();
  473. if (selectedItem == null) {
  474. btnOpenWith.IsEnabled = false;
  475. } else {
  476. var mnu = new ShellContextMenu(this._ShellListView, false);
  477. try {
  478. var tempPoint = btnOpenWith.PointToScreen(new WIN.Point(0, 0));
  479. var itemMenuCount = mnu.ShowContextMenu(new System.Drawing.Point((int)tempPoint.X, (int)tempPoint.Y + (int)btnOpenWith.ActualHeight), 1, false);
  480. btnOpenWith.IsEnabled = itemMenuCount > 0 && selItemsCount == 1;
  481. } catch {
  482. btnOpenWith.IsEnabled = false;
  483. }
  484. }
  485. btnNewItem.IsEnabled = this._ShellListView.CurrentFolder.IsFileSystem || this._ShellListView.CurrentFolder.ParsingName == KnownFolders.Libraries.ParsingName;
  486. if (selectedItem != null && selectedItem.IsFileSystem && BESettings.IsPreviewPaneEnabled && !selectedItem.IsFolder && selItemsCount == 1)
  487. this.Previewer.FileName = selectedItem.ParsingName;
  488. else if (!String.IsNullOrEmpty(this.Previewer.FileName))
  489. this.Previewer.FileName = null;
  490. //Set up ribbon contextual tabs on selection changed
  491. SetUpRibbonTabsVisibilityOnSelectOrNavigate(selItemsCount, selectedItem);
  492. SetUpButtonsStateOnSelectOrNavigate(selItemsCount, selectedItem);
  493. }));
  494. }
  495. bool IsFromSelectionOrNavigation = false;
  496. void cbm_ClipboardChanged(object sender, Tuple<WIN.Forms.IDataObject> e) {
  497. btnPaste.IsEnabled = e.Item1.GetDataPresent(DataFormats.FileDrop) || e.Item1.GetDataPresent("Shell IDList Array");
  498. btnPasetShC.IsEnabled = e.Item1.GetDataPresent(DataFormats.FileDrop) || e.Item1.GetDataPresent("Shell IDList Array");
  499. }
  500. #endregion
  501. #region Conditional Select
  502. private void miSelAllByType_Click(object sender, RoutedEventArgs e) {
  503. if (_ShellListView.GetSelectedCount() > 0) {
  504. var typePK = new PROPERTYKEY() { fmtid = Guid.Parse("B725F130-47EF-101A-A5F1-02608C9EEBAC"), pid = 4 };
  505. var flt = _ShellListView.SelectedItems.Select(item => item.GetPropertyValue(typePK, typeof(String)).Value.ToString().ToLowerInvariant());
  506. var items = _ShellListView.Items.Where(w => flt.Contains(w.GetPropertyValue(typePK, typeof(String)).Value.ToString().ToLowerInvariant())).ToArray();
  507. _ShellListView.SelectItems(items);
  508. btnCondSel.IsDropDownOpen = false;
  509. }
  510. }
  511. private void miSelAllByDate_Click(object sender, RoutedEventArgs e) {
  512. if (_ShellListView.GetSelectedCount() > 0) {
  513. var typePK = new PROPERTYKEY() { fmtid = Guid.Parse("b725f130-47ef-101a-a5f1-02608c9eebac"), pid = 15 };
  514. var flt = _ShellListView.SelectedItems.Select(item => DateTime.Parse(item.GetPropertyValue(typePK, typeof(String)).Value.ToString().ToLowerInvariant()).Date);
  515. var items = _ShellListView.Items.Where(w => flt.Contains(DateTime.Parse(w.GetPropertyValue(typePK, typeof(String)).Value.ToString().ToLowerInvariant()).Date)).ToArray();
  516. _ShellListView.SelectItems(items);
  517. btnCondSel.IsDropDownOpen = false;
  518. }
  519. }
  520. private void btnCondSel_Click(object sender, RoutedEventArgs e) {
  521. btnCondSel.IsDropDownOpen = false;
  522. ConditionalSelectForm.Open(_ShellListView);
  523. }
  524. #endregion
  525. #region Size Chart
  526. private void btnFSizeChart_Click(object sender, RoutedEventArgs e) {
  527. if (_ShellListView.GetSelectedCount() > 0) {
  528. if ((_ShellListView.GetFirstSelectedItem().IsFolder || _ShellListView.GetFirstSelectedItem().IsDrive) && _ShellListView.GetFirstSelectedItem().IsFileSystem) {
  529. FolderSizeWindow.Open(_ShellListView.GetFirstSelectedItem().ParsingName, this);
  530. return;
  531. }
  532. } else if ((_ShellListView.CurrentFolder.IsFolder || _ShellListView.CurrentFolder.IsDrive) && _ShellListView.CurrentFolder.IsFileSystem) {
  533. FolderSizeWindow.Open(_ShellListView.CurrentFolder.ParsingName, this);
  534. }
  535. }
  536. private void btnSizeChart_Click(object sender, RoutedEventArgs e) {
  537. FolderSizeWindow.Open(_ShellListView.CurrentFolder.ParsingName, this);
  538. }
  539. #endregion
  540. #region Home Tab
  541. private void btnctDocuments_Click(object sender, RoutedEventArgs e) => SetFOperation(KnownFolders.Documents.ParsingName, OperationType.Copy);
  542. private void btnctDesktop_Click(object sender, RoutedEventArgs e) => SetFOperation(KnownFolders.Desktop.ParsingName, OperationType.Copy);
  543. private void btnctDounloads_Click(object sender, RoutedEventArgs e) => SetFOperation(KnownFolders.Downloads.ParsingName, OperationType.Copy);
  544. private void btnmtDocuments_Click(object sender, RoutedEventArgs e) => SetFOperation(KnownFolders.Documents.ParsingName, OperationType.Move);
  545. private void btnmtDesktop_Click(object sender, RoutedEventArgs e) => SetFOperation(KnownFolders.Desktop.ParsingName, OperationType.Move);
  546. private void btnmtDounloads_Click(object sender, RoutedEventArgs e) => SetFOperation(KnownFolders.Downloads.ParsingName, OperationType.Move);
  547. private void btnCopyto_Click(object sender, RoutedEventArgs e) => btnctOther_Click(sender, e);
  548. private void btnMoveto_Click(object sender, RoutedEventArgs e) => btnmtOther_Click(sender, e);
  549. private void btnCut_Click(object sender, RoutedEventArgs e) => _ShellListView.CutSelectedFiles();
  550. private void btnOpenWith_Click(object sender, RoutedEventArgs e) => Process.Start($"\"{_ShellListView.GetFirstSelectedItem().ParsingName}\"");
  551. private void btnPaste_Click(object sender, RoutedEventArgs e) => _ShellListView.PasteAvailableFiles();
  552. private void btnDelete_Click(object sender, RoutedEventArgs e) => MenuItem_Click(sender, e);
  553. private void btnRename_Click(object sender, RoutedEventArgs e) => _ShellListView.RenameSelectedItem();
  554. private void btnSelAll_Click(object sender, RoutedEventArgs e) => _ShellListView.SelectAll();
  555. private void btnSelNone_Click(object sender, RoutedEventArgs e) => _ShellListView.DeSelectAllItems();
  556. private void MenuItem_Click(object sender, RoutedEventArgs e) => _ShellListView.DeleteSelectedFiles(true);
  557. private void MenuItem_Click_1(object sender, RoutedEventArgs e) => _ShellListView.DeleteSelectedFiles(false);
  558. private void btnProperties_Click(object sender, RoutedEventArgs e) => _ShellListView.ShowPropPage(this.Handle, _ShellListView.GetFirstSelectedItem().ParsingName, "");
  559. private void btnInvSel_Click(object sender, RoutedEventArgs e) => _ShellListView.InvertSelection();
  560. private void btnNewWindow_Click(object sender, RoutedEventArgs e) => Process.Start(Assembly.GetExecutingAssembly().Location, "/nw");
  561. void miow_Click(object sender, RoutedEventArgs e) => ((AssociationItem)(sender as MenuItem).Tag).Invoke();
  562. private void miJunctionpoint_Click(object sender, RoutedEventArgs e) {
  563. string pathForDrop = _ShellListView.CurrentFolder.ParsingName.Replace(@"\\", @"\");
  564. var files = new string[0];
  565. if (Clipboards.ContainsData("Shell IDList Array"))
  566. files = Clipboards.GetDataObject().ToShellItemArray().ToArray().Select(s => new ShellItem(s).ParsingName).ToArray();
  567. else
  568. files = Clipboards.GetFileDropList().OfType<string>().ToArray();
  569. foreach (string item in files) {
  570. var o = new ShellItem(item);
  571. JunctionPointUtils.JunctionPoint.Create($@"{pathForDrop}\{o.GetDisplayName(SIGDN.NORMALDISPLAY)}", o.ParsingName, true);
  572. AddToLog($@"Created Junction Point at {pathForDrop}\{o.GetDisplayName(SIGDN.NORMALDISPLAY)} linked to {o.ParsingName}");
  573. }
  574. }
  575. private void miCreateSymlink_Click(object sender, RoutedEventArgs e) {
  576. var items = new IListItemEx[0];
  577. items = Clipboards.ContainsData("Shell IDList Array") ? Clipboards.GetDataObject().ToShellItemArray().ToArray().Select(s => FileSystemListItem.InitializeWithIShellItem(this._ShellListView.LVHandle, s)).ToArray() : Clipboards.GetFileDropList().OfType<string>().ToArray().Select(s => FileSystemListItem.ToFileSystemItem(this._ShellListView.LVHandle, s)).ToArray();
  578. var pathForDrop = _ShellListView.CurrentFolder.ParsingName.Replace(@"\\", @"\");
  579. var exePath = Utilities.AppDirectoryItem("BetterExplorerOperations.exe");
  580. var linkItems = items.Select(s => new LinkItem() {
  581. IsDirectory = s.IsFolder,
  582. DestinationData = pathForDrop + @"\" + s.DisplayName,
  583. SourceData = s.ParsingName
  584. }).ToArray();
  585. Task.Run(() => {
  586. using (var proc = new Process()) {
  587. proc.StartInfo = new ProcessStartInfo {
  588. FileName = exePath,
  589. Verb = "runas",
  590. UseShellExecute = true,
  591. Arguments = $"/env /user:Administrator \"{exePath}\""
  592. };
  593. proc.Start();
  594. ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
  595. var address = new EndpointAddress(new Uri("net.tcp://localhost:60000/BEComChannel"));
  596. var binding = new NetTcpBinding() { MaxReceivedMessageSize = 4000000, MaxBufferPoolSize = 4000000, MaxBufferSize = 4000000 };
  597. binding.Security = new NetTcpSecurity() { Mode = SecurityMode.Message };
  598. var factory = new ChannelFactory<IBetterExplorerCommunication>(binding, address);
  599. var beSvc = factory.CreateChannel();
  600. try {
  601. beSvc.CreateLink(new LinkData() { Items = linkItems });
  602. } finally {
  603. Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => this._ShellListView.UnvalidateDirectory()));
  604. }
  605. proc.WaitForExit();
  606. if (proc.ExitCode == 1)
  607. MessageBox.Show("Error in creating symlink", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
  608. else {
  609. Thread.Sleep(1000);
  610. Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => this._ShellListView.UnvalidateDirectory()));
  611. }
  612. }
  613. });
  614. }
  615. private void btnHistory_Click(object sender, RoutedEventArgs e) {
  616. _ShellListView.ShowPropPage(this.Handle, _ShellListView.GetFirstSelectedItem().ParsingName,
  617. User32.LoadResourceString(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "twext.dll"), 1024, "Previous Versions"));
  618. }
  619. private void btnBackstageExit_Click(object sender, RoutedEventArgs e) {
  620. //! We call Shutdown() so to explicit shutdown the app regardless of windows closing cancel flag.
  621. if (this.IsMultipleWindowsOpened)
  622. this.Close();
  623. else
  624. Application.Current.Shutdown();
  625. }
  626. void mif_Click(object sender, RoutedEventArgs e) {
  627. using (var obj = (sender as MenuItem).Tag as ShellItem)
  628. using (var lnk = new ShellLink(obj.ParsingName)) {
  629. NavigationController(FileSystemListItem.ToFileSystemItem(this._ShellListView.LVHandle, lnk.TargetPIDL));
  630. }
  631. }
  632. private void btnCopy_Click(object sender, RoutedEventArgs e) {
  633. var sc = new StringCollection();
  634. sc.AddRange(_ShellListView.SelectedItems.Select(x => x.ParsingName).ToArray());
  635. Clipboards.SetFileDropList(sc);
  636. }
  637. private void btnPathCopy_Click(object sender, RoutedEventArgs e) {
  638. if (_ShellListView.SelectedItems.Count > 1)
  639. Clipboards.SetText(_ShellListView.SelectedItems.Select(item => "\r\n" + item.ParsingName).Aggregate((x, y) => x + y).Trim());
  640. else if (_ShellListView.SelectedItems.Count == 1)
  641. Clipboards.SetText(_ShellListView.GetFirstSelectedItem().ParsingName);
  642. else
  643. Clipboards.SetText(_ShellListView.CurrentFolder.ParsingName);
  644. }
  645. // New Folder/Library
  646. private void btnNewFolder_Library(object sender, RoutedEventArgs e) {
  647. //We should focus the ListView or on some circumstances new folder does not start renaming after folder is created
  648. this._ShellListView.Focus();
  649. _ShellListView.IsRenameNeeded = true;
  650. if (_ShellListView.CurrentFolder.ParsingName == KnownFolders.Libraries.ParsingName)
  651. _ShellListView.CreateNewLibrary(FindResource("btnNewLibraryCP").ToString());
  652. else
  653. _ShellListView.CreateNewFolder(null);
  654. }
  655. private void btnPasetShC_Click(object sender, RoutedEventArgs e) {
  656. string PathForDrop = _ShellListView.CurrentFolder.ParsingName;
  657. foreach (string item in Clipboards.GetFileDropList()) {
  658. using (var shortcut = new ShellLink()) {
  659. var o = new ShellItem(item);
  660. shortcut.Target = item;
  661. shortcut.WorkingDirectory = Path.GetDirectoryName(item);
  662. shortcut.Description = o.GetDisplayName(SIGDN.NORMALDISPLAY);
  663. shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
  664. shortcut.Save($"{PathForDrop}\\{o.GetDisplayName(SIGDN.NORMALDISPLAY)}.lnk");
  665. AddToLog($"Shortcut created at {PathForDrop}\\{o.GetDisplayName(SIGDN.NORMALDISPLAY)} from source {item}");
  666. }
  667. }
  668. }
  669. private void btnmtOther_Click(object sender, RoutedEventArgs e) {
  670. var dlg = new FolderSelectDialog();
  671. if (dlg.ShowDialog())
  672. SetFOperation(dlg.FileName, OperationType.Move);
  673. }
  674. private void SetFOperation(String fileName, OperationType opType) {
  675. var obj = FileSystemListItem.ToFileSystemItem(this._ShellListView.LVHandle, fileName.ToShellParsingName());
  676. if (opType == OperationType.Copy)
  677. _ShellListView.DoCopy(obj);
  678. else if (opType == OperationType.Move)
  679. _ShellListView.DoMove(obj);
  680. }
  681. private void SetFOperation(IListItemEx obj, OperationType opType) {
  682. if (opType == OperationType.Copy)
  683. _ShellListView.DoCopy(obj);
  684. else if (opType == OperationType.Move)
  685. _ShellListView.DoMove(obj);
  686. }
  687. private void btnctOther_Click(object sender, RoutedEventArgs e) {
  688. var dlg = new FolderSelectDialog();
  689. if (dlg.ShowDialog())
  690. SetFOperation(dlg.FileName, OperationType.Copy);
  691. _ShellListView.Focus();
  692. }
  693. private void btnNewItem_Click(object sender, RoutedEventArgs e) {
  694. var state = new BExplorer.Shell.Interop.Shell32.SHELLSTATE() { fShowAllObjects = 0 };
  695. BExplorer.Shell.Interop.Shell32.SHGetSetSettings(ref state, BExplorer.Shell.Interop.Shell32.SSF.SSF_SHOWALLOBJECTS, true);
  696. }
  697. private void btnEdit_Click(object sender, RoutedEventArgs e) {
  698. new Process() {
  699. StartInfo = new ProcessStartInfo {
  700. FileName = _ShellListView.GetFirstSelectedItem().ParsingName,
  701. Verb = "edit",
  702. UseShellExecute = true,
  703. }
  704. }.Start();
  705. }
  706. private void btnFavorites_Click(object sender, RoutedEventArgs e) {
  707. var selectedItems = _ShellListView.SelectedItems;
  708. if (selectedItems.Count == 1) {
  709. var link = new ShellLink();
  710. link.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
  711. link.Target = _ShellListView.GetFirstSelectedItem().ParsingName;
  712. link.Save($@"{KnownFolders.Links.ParsingName}\{_ShellListView.GetFirstSelectedItem().DisplayName}.lnk");
  713. link.Dispose();
  714. }
  715. if (selectedItems.Count == 0) {
  716. var link = new ShellLink();
  717. link.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
  718. link.Target = _ShellListView.CurrentFolder.ParsingName;
  719. link.Save($@"{KnownFolders.Links.ParsingName}\{_ShellListView.CurrentFolder.DisplayName}.lnk");
  720. link.Dispose();
  721. }
  722. }
  723. #endregion
  724. #region Drive Tools / Virtual Disk Tools
  725. private void btnDefragDrive_Click(object sender, RoutedEventArgs e) {
  726. string DriveLetter = "";
  727. if (!_ShellListView.SelectedItems.Any())
  728. DriveLetter = _ShellListView.CurrentFolder.ParsingName;
  729. else if (Directory.GetLogicalDrives().Contains(_ShellListView.SelectedItems[0].ParsingName))
  730. DriveLetter = _ShellListView.SelectedItems[0].ParsingName;
  731. else
  732. DriveLetter = _ShellListView.CurrentFolder.ParsingName;
  733. Process.Start(Path.Combine(Environment.SystemDirectory, "dfrgui.exe"), $"/u /v {DriveLetter.Replace("\\", "")}");
  734. }
  735. private char GetDriveLetterFromDrivePath(string path) => path.Substring(0, 1).ToCharArray()[0];
  736. private void btnFormatDrive_Click(object sender, RoutedEventArgs e) {
  737. if (MessageBox.Show("Are you sure you want to do this?", FindResource("btnFormatDriveCP").ToString(), MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes) {
  738. var formatDriveThread = new Thread(() => {
  739. string DriveLetter =
  740. _ShellListView.SelectedItems.Any() ?
  741. DriveLetter = Directory.GetLogicalDrives().Contains(_ShellListView.SelectedItems[0].ParsingName) ? _ShellListView.SelectedItems[0].ParsingName : _ShellListView.CurrentFolder.ParsingName
  742. :
  743. DriveLetter = _ShellListView.CurrentFolder.ParsingName;
  744. BExplorer.Shell.Interop.Shell32.FormatDrive(IntPtr.Zero, DriveLetter);
  745. });
  746. formatDriveThread.Start();
  747. }
  748. }
  749. private void btnCleanDrive_Click(object sender, RoutedEventArgs e) {
  750. string DriveLetter = "";
  751. if (_ShellListView.SelectedItems.Any())
  752. DriveLetter = Directory.GetLogicalDrives().Contains(_ShellListView.SelectedItems[0].ParsingName) ? _ShellListView.SelectedItems[0].ParsingName : _ShellListView.CurrentFolder.ParsingName;
  753. else
  754. DriveLetter = _ShellListView.CurrentFolder.ParsingName;
  755. Process.Start("Cleanmgr.exe", "/d" + DriveLetter.Replace(":\\", ""));
  756. }
  757. private void OpenCDTray(char DriveLetter) {
  758. mciSendString($"open {DriveLetter}: type CDAudio alias drive{DriveLetter}", null, 0, IntPtr.Zero);
  759. mciSendString($"set drive{DriveLetter} door open", null, 0, IntPtr.Zero);
  760. }
  761. private void CloseCDTray(char DriveLetter) {
  762. mciSendString($"open {DriveLetter}: type CDAudio alias drive{DriveLetter}", null, 0, IntPtr.Zero);
  763. mciSendString($"set drive{DriveLetter} door closed", null, 0, IntPtr.Zero);
  764. }
  765. private void btnOpenTray_Click(object sender, RoutedEventArgs e) {
  766. if (_ShellListView.GetFirstSelectedItem()?.GetDriveInfo().DriveType == DriveType.CDRom)
  767. OpenCDTray(GetDriveLetterFromDrivePath(_ShellListView.GetFirstSelectedItem().ParsingName));
  768. }
  769. private void btnCloseTray_Click(object sender, RoutedEventArgs e) {
  770. if (_ShellListView.GetFirstSelectedItem()?.GetDriveInfo().DriveType == DriveType.CDRom)
  771. CloseCDTray(GetDriveLetterFromDrivePath(_ShellListView.GetFirstSelectedItem().ParsingName));
  772. }
  773. private void EjectDisk(char DriveLetter) {
  774. Thread t = new Thread(() => {
  775. Thread.Sleep(10);
  776. var vdc = new VolumeDeviceClass();
  777. foreach (Volume item in vdc.Devices) {
  778. if (GetDriveLetterFromDrivePath(item.LogicalDrive) == DriveLetter) {
  779. var veto = item.Eject(false);
  780. if (veto != Native.PNP_VETO_TYPE.TypeUnknown) {
  781. if (veto == Native.PNP_VETO_TYPE.Ok) {
  782. Dispatcher.BeginInvoke(DispatcherPriority.Normal,
  783. (Action)(() => {
  784. this.beNotifyIcon.ShowBalloonTip("Information", $"It is safe to remove {item.LogicalDrive}", Hardcodet.Wpf.TaskbarNotification.BalloonIcon.Info);
  785. var tabsForRemove = tcMain.Items.OfType<Wpf.Controls.TabItem>().Where(w => {
  786. var root = String.Empty;
  787. try {
  788. root = Path.GetPathRoot(w.ShellObject.ParsingName.ToShellParsingName());
  789. } catch { }
  790. return !String.IsNullOrEmpty(root) && (w.ShellObject.IsFileSystem &&
  791. root.ToLowerInvariant() == $"{DriveLetter}:\\".ToLowerInvariant());
  792. }).ToArray();
  793. foreach (Wpf.Controls.TabItem tab in tabsForRemove) {
  794. tcMain.RemoveTabItem(tab);
  795. }
  796. }));
  797. } else {
  798. var message = String.Empty;
  799. var obj = new ShellItem(item.LogicalDrive);
  800. switch (veto) {
  801. case Native.PNP_VETO_TYPE.Ok:
  802. break;
  803. case Native.PNP_VETO_TYPE.TypeUnknown:
  804. break;
  805. case Native.PNP_VETO_TYPE.LegacyDevice:
  806. break;
  807. case Native.PNP_VETO_TYPE.PendingClose:
  808. break;
  809. case Native.PNP_VETO_TYPE.WindowsApp:
  810. break;
  811. case Native.PNP_VETO_TYPE.WindowsService:
  812. break;
  813. case Native.PNP_VETO_TYPE.OutstandingOpen:
  814. message = $"The device {obj.GetDisplayName(SIGDN.NORMALDISPLAY)} can not be disconnected because is in use!";
  815. break;
  816. case Native.PNP_VETO_TYPE.Device:
  817. break;
  818. case Native.PNP_VETO_TYPE.Driver:
  819. break;
  820. case Native.PNP_VETO_TYPE.IllegalDeviceRequest:
  821. break;
  822. case Native.PNP_VETO_TYPE.InsufficientPower:
  823. break;
  824. case Native.PNP_VETO_TYPE.NonDisableable:
  825. message = $"The device {obj.GetDisplayName(SIGDN.NORMALDISPLAY)} does not support disconnecting!";
  826. break;
  827. case Native.PNP_VETO_TYPE.LegacyDriver:
  828. break;
  829. default:
  830. break;
  831. }
  832. Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => this.beNotifyIcon.ShowBalloonTip("Error", message, Hardcodet.Wpf.TaskbarNotification.BalloonIcon.Error)));
  833. }
  834. }
  835. break;
  836. }
  837. }
  838. });
  839. t.SetApartmentState(ApartmentState.STA);
  840. t.Start();
  841. }
  842. private void btnEjectDevice_Click(object sender, RoutedEventArgs e) {
  843. var firstSelectedItem = _ShellListView.GetFirstSelectedItem();
  844. if (firstSelectedItem?.GetDriveInfo().DriveType == DriveType.Removable || firstSelectedItem.GetDriveInfo().DriveType == DriveType.Fixed) {
  845. EjectDisk(GetDriveLetterFromDrivePath(firstSelectedItem.ParsingName));
  846. //USBEject.EjectDrive(GetDriveLetterFromDrivePath(firstSelectedItem.ParsingName));
  847. }
  848. }
  849. // Virtual Disk Tools
  850. private bool CheckImDiskInstalled() {
  851. try {
  852. ImDiskAPI.GetDeviceList();
  853. return true;
  854. } catch (DllNotFoundException) {
  855. return false;
  856. }
  857. }
  858. public void ShowInstallImDiskMessage() {
  859. if (MessageBox.Show("It appears you do not have the ImDisk Virtual Disk Driver installed. This driver is used to power Better Explorer's ISO-mounting features. \n\nWould you like to visit ImDisk's website to install the product? (http://www.ltr-data.se/opencode.html/)", "ImDisk Not Found", MessageBoxButton.YesNo, MessageBoxImage.Error) == MessageBoxResult.Yes) {
  860. Process.Start("http://www.ltr-data.se/opencode.html/#ImDisk");
  861. }
  862. }
  863. private void btnAdvMountIso_Click(object sender, RoutedEventArgs e) {
  864. if (!CheckImDiskInstalled()) {
  865. ShowInstallImDiskMessage();
  866. return;
  867. }
  868. var mi = new MountIso() { Owner = this };
  869. mi.ShowDialog();
  870. if (mi.yep) {
  871. string DriveLetter = String.Format("{0}:", mi.chkPreselect.IsChecked == true ? ImDiskAPI.FindFreeDriveLetter() : (char)mi.cbbLetter.SelectedItem);
  872. long size = mi.chkPresized.IsChecked == true ? 0 : Convert.ToInt64(mi.txtSize.Text);
  873. ImDiskFlags i

Large files files are truncated, but you can click here to view the full file