2023-04-17 00:17:33 +12:00
|
|
|
|
// <copyright file="DirectoryHelpers.cs" company="PlaceholderCompany">
|
|
|
|
|
// Copyright (c) PlaceholderCompany. All rights reserved.
|
|
|
|
|
// </copyright>
|
|
|
|
|
|
|
|
|
|
namespace SystemTrayMenu.Helpers
|
|
|
|
|
{
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using SystemTrayMenu.DataClasses;
|
|
|
|
|
using SystemTrayMenu.Utilities;
|
|
|
|
|
|
|
|
|
|
internal static class DirectoryHelpers
|
|
|
|
|
{
|
|
|
|
|
internal static void DiscoverItems(BackgroundWorker? worker, string path, ref MenuData menuData)
|
|
|
|
|
{
|
2023-04-28 08:19:02 +12:00
|
|
|
|
bool isNetworkRoot = false;
|
2023-04-17 00:17:33 +12:00
|
|
|
|
try
|
2023-04-16 08:19:16 +12:00
|
|
|
|
{
|
2023-04-28 08:19:02 +12:00
|
|
|
|
isNetworkRoot = FileLnk.IsNetworkRoot(path);
|
|
|
|
|
if (isNetworkRoot)
|
2023-04-17 00:17:33 +12:00
|
|
|
|
{
|
|
|
|
|
DiscoverNetworkRootDirectories(path, ref menuData);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DiscoverLocalDirectories(worker, path, ref menuData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Warn($"path:'{path}'", ex);
|
|
|
|
|
if (ex is UnauthorizedAccessException)
|
|
|
|
|
{
|
|
|
|
|
menuData.DirectoryState = MenuDataDirectoryState.NoAccess;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (worker?.CancellationPending == true)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (menuData.Level == 0)
|
|
|
|
|
{
|
|
|
|
|
foreach (var additionalPath in GetAddionalPathsForMainMenu())
|
|
|
|
|
{
|
|
|
|
|
GetDirectoriesAndFilesRecursive(ref menuData, additionalPath.Path, additionalPath.OnlyFiles, additionalPath.Recursive);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-28 08:19:02 +12:00
|
|
|
|
RemoveHiddenOrReadIcons(worker, isNetworkRoot, ref menuData);
|
2023-04-17 00:17:33 +12:00
|
|
|
|
|
|
|
|
|
if (menuData.RowDatas.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
menuData.DirectoryState = MenuDataDirectoryState.Empty;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (worker?.CancellationPending == true)
|
2023-04-16 08:19:16 +12:00
|
|
|
|
{
|
|
|
|
|
return;
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
menuData.RowDatas = SortItems(menuData.RowDatas);
|
|
|
|
|
menuData.DirectoryState = MenuDataDirectoryState.Valid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static IEnumerable<(string Path, bool Recursive, bool OnlyFiles)> GetAddionalPathsForMainMenu()
|
|
|
|
|
{
|
|
|
|
|
foreach (string pathAndRecursivString in Properties.Settings.Default.PathsAddToMainMenu.Split(@"|"))
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(pathAndRecursivString))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string pathAddForMainMenu = pathAndRecursivString.Split("recursiv:")[0].Trim();
|
|
|
|
|
bool recursive = pathAndRecursivString.Split("recursiv:")[1].StartsWith("True");
|
|
|
|
|
bool onlyFiles = pathAndRecursivString.Split("onlyFiles:")[1].StartsWith("True");
|
|
|
|
|
yield return (Path: pathAddForMainMenu, Recursive: recursive, OnlyFiles: onlyFiles);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static List<RowData> SortItems(List<RowData> rowDatas)
|
|
|
|
|
{
|
|
|
|
|
if (Properties.Settings.Default.SortByTypeAndNameWindowsExplorerSort)
|
|
|
|
|
{
|
|
|
|
|
rowDatas = rowDatas.OrderByDescending(x => x.IsFolder)
|
2023-05-20 06:43:19 +12:00
|
|
|
|
.ThenBy(x => x.ColumnText, new WindowsExplorerSort()).ToList();
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
else if (Properties.Settings.Default.SortByTypeAndDate)
|
|
|
|
|
{
|
|
|
|
|
rowDatas = rowDatas.OrderByDescending(x => x.IsFolder)
|
2023-04-30 04:57:39 +12:00
|
|
|
|
.ThenByDescending(x => x.FileInfo.LastWriteTime).ToList();
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
else if (Properties.Settings.Default.SortByFileExtensionAndName)
|
|
|
|
|
{
|
2023-05-20 06:43:19 +12:00
|
|
|
|
rowDatas = rowDatas.OrderBy(x => x.FileExtension).ThenBy(x => x.ColumnText).ToList();
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
else if (Properties.Settings.Default.SortByName)
|
|
|
|
|
{
|
2023-05-20 06:43:19 +12:00
|
|
|
|
rowDatas = rowDatas.OrderBy(x => x.ColumnText).ToList();
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
else if (Properties.Settings.Default.SortByDate)
|
|
|
|
|
{
|
2023-04-30 04:57:39 +12:00
|
|
|
|
rowDatas = rowDatas.OrderByDescending(x => x.FileInfo.LastWriteTime).ToList();
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rowDatas;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-28 08:19:02 +12:00
|
|
|
|
private static void RemoveHiddenOrReadIcons(BackgroundWorker? worker, bool isNetworkRoot, ref MenuData menuData)
|
2023-04-17 00:17:33 +12:00
|
|
|
|
{
|
|
|
|
|
List<RowData> rowDatasToRemove = new();
|
|
|
|
|
foreach (RowData rowData in menuData.RowDatas)
|
|
|
|
|
{
|
|
|
|
|
if (worker?.CancellationPending == true)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-28 08:19:02 +12:00
|
|
|
|
if (!isNetworkRoot)
|
2023-04-17 00:17:33 +12:00
|
|
|
|
{
|
2023-04-28 07:11:20 +12:00
|
|
|
|
FolderOptions.ReadHiddenAttributes(rowData.Path, out bool hasHiddenFlag, out bool isDirectoryToHide);
|
|
|
|
|
if (isDirectoryToHide)
|
|
|
|
|
{
|
|
|
|
|
rowDatasToRemove.Add(rowData);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rowData.HiddenEntry = hasHiddenFlag;
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-20 04:50:53 +12:00
|
|
|
|
rowData.LoadIcon();
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
menuData.RowDatas = menuData.RowDatas.Except(rowDatasToRemove).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void DiscoverNetworkRootDirectories(string path, ref MenuData menuData)
|
|
|
|
|
{
|
|
|
|
|
Process cmd = new();
|
|
|
|
|
cmd.StartInfo.FileName = "cmd.exe";
|
|
|
|
|
cmd.StartInfo.RedirectStandardInput = true;
|
|
|
|
|
cmd.StartInfo.RedirectStandardOutput = true;
|
|
|
|
|
cmd.StartInfo.CreateNoWindow = true;
|
|
|
|
|
cmd.StartInfo.UseShellExecute = false;
|
|
|
|
|
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
|
|
|
|
|
|
|
|
|
cmd.Start();
|
|
|
|
|
cmd.StandardInput.WriteLine($"net view {path}");
|
|
|
|
|
cmd.StandardInput.Flush();
|
|
|
|
|
cmd.StandardInput.Close();
|
|
|
|
|
string output = cmd.StandardOutput.ReadToEnd();
|
|
|
|
|
cmd.WaitForExit();
|
|
|
|
|
cmd.Close();
|
|
|
|
|
|
|
|
|
|
bool resolvedSomething = false;
|
|
|
|
|
List<string> lines = output
|
|
|
|
|
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
|
|
|
|
if (lines.Count > 8)
|
|
|
|
|
{
|
|
|
|
|
foreach (string line in lines.Skip(6).SkipLast(2))
|
|
|
|
|
{
|
|
|
|
|
int indexOfFirstSpace = line.IndexOf(" ", StringComparison.InvariantCulture);
|
|
|
|
|
if (indexOfFirstSpace > 0)
|
|
|
|
|
{
|
|
|
|
|
string directory = Path.Combine(path, line[..indexOfFirstSpace]);
|
2023-04-29 04:48:39 +12:00
|
|
|
|
menuData.RowDatas.Add(new RowData(true, false, menuData.Level, directory));
|
2023-04-17 00:17:33 +12:00
|
|
|
|
resolvedSomething = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!resolvedSomething)
|
|
|
|
|
{
|
|
|
|
|
Log.Info($"Could not resolve network root folder: {path} , output:{output}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void DiscoverLocalDirectories(BackgroundWorker? worker, string path, ref MenuData menuData)
|
|
|
|
|
{
|
|
|
|
|
if (!Directory.Exists(path))
|
|
|
|
|
{
|
|
|
|
|
// Happens most likely when a shortcut is pointing to an absent target path
|
|
|
|
|
Log.Info($"path:'{path}' does not exist");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var directory in Directory.GetDirectories(path))
|
|
|
|
|
{
|
|
|
|
|
if (worker?.CancellationPending == true)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-29 04:48:39 +12:00
|
|
|
|
menuData.RowDatas.Add(new RowData(true, false, menuData.Level, directory));
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-10 09:33:56 +12:00
|
|
|
|
foreach (string file in GetFilesBySearchPattern(path, Config.SearchPattern))
|
2023-04-17 00:17:33 +12:00
|
|
|
|
{
|
|
|
|
|
if (worker?.CancellationPending == true)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-29 04:48:39 +12:00
|
|
|
|
menuData.RowDatas.Add(new RowData(false, false, menuData.Level, file));
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void GetDirectoriesAndFilesRecursive(
|
|
|
|
|
ref MenuData menuData,
|
|
|
|
|
string path,
|
|
|
|
|
bool onlyFiles,
|
|
|
|
|
bool recursiv)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2023-05-10 09:33:56 +12:00
|
|
|
|
foreach (string file in GetFilesBySearchPattern(path, Config.SearchPattern))
|
2023-04-17 00:17:33 +12:00
|
|
|
|
{
|
2023-04-29 04:48:39 +12:00
|
|
|
|
menuData.RowDatas.Add(new RowData(false, true, menuData.Level, file));
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (string directory in Directory.GetDirectories(path))
|
|
|
|
|
{
|
|
|
|
|
if (!onlyFiles)
|
|
|
|
|
{
|
2023-04-29 04:48:39 +12:00
|
|
|
|
menuData.RowDatas.Add(new RowData(true, true, menuData.Level, directory));
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (recursiv)
|
|
|
|
|
{
|
|
|
|
|
GetDirectoriesAndFilesRecursive(ref menuData, directory, onlyFiles, recursiv);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Warn($"GetDirectoriesAndFilesRecursive path:'{path}'", ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-10 09:33:56 +12:00
|
|
|
|
|
|
|
|
|
private static List<string> GetFilesBySearchPattern(string path, string searchPatternCombined)
|
|
|
|
|
{
|
|
|
|
|
string[] searchPatterns = searchPatternCombined.Split('|');
|
|
|
|
|
List<string> files = new();
|
|
|
|
|
foreach (string searchPattern in searchPatterns)
|
|
|
|
|
{
|
|
|
|
|
files.AddRange(Directory.GetFiles(path, searchPattern));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return files;
|
|
|
|
|
}
|
2023-04-17 00:17:33 +12:00
|
|
|
|
}
|
2023-05-10 09:33:56 +12:00
|
|
|
|
}
|