diff --git a/Business/Menus.cs b/Business/Menus.cs index ed1ba8a..b1d894e 100644 --- a/Business/Menus.cs +++ b/Business/Menus.cs @@ -1110,12 +1110,14 @@ namespace SystemTrayMenu.Business } RowData rowDataRenamed = new(isFolder, rowData.IsAdditionalItem, false, 0, path); - if (FolderOptions.IsHidden(rowDataRenamed)) + FolderOptions.ReadHiddenAttributes(rowDataRenamed.Path, out bool hasHiddenFlag, out bool isDirectoryToHide); + if (isDirectoryToHide) { continue; } IconReader.RemoveIconFromCache(rowData.Path); + rowDataRenamed.HiddenEntry = hasHiddenFlag; rowDataRenamed.ReadIcon(true); rowDatas.Add(rowDataRenamed); } @@ -1188,11 +1190,13 @@ namespace SystemTrayMenu.Business bool isFolder = (attr & FileAttributes.Directory) == FileAttributes.Directory; bool isAddionalItem = Path.GetDirectoryName(e.FullPath) != Config.Path; RowData rowData = new(isFolder, isAddionalItem, false, 0, e.FullPath); - if (FolderOptions.IsHidden(rowData)) + FolderOptions.ReadHiddenAttributes(rowData.Path, out bool hasHiddenFlag, out bool isDirectoryToHide); + if (isDirectoryToHide) { return; } + rowData.HiddenEntry = hasHiddenFlag; rowData.ReadIcon(true); List rowDatas = new() diff --git a/DataClasses/RowData.cs b/DataClasses/RowData.cs index aaf69bb..9eb1f6c 100644 --- a/DataClasses/RowData.cs +++ b/DataClasses/RowData.cs @@ -18,14 +18,6 @@ namespace SystemTrayMenu.DataClasses { private static DateTime contextMenuClosed; - /// - /// Initializes a new instance of the class. - /// empty dummy. - /// - internal RowData() - { - } - /// /// Initializes a new instance of the class. /// (Related replace "\x00" see #171.) diff --git a/Helpers/DirectoryHelpers.cs b/Helpers/DirectoryHelpers.cs index 1922f50..4fb108e 100644 --- a/Helpers/DirectoryHelpers.cs +++ b/Helpers/DirectoryHelpers.cs @@ -125,10 +125,16 @@ namespace SystemTrayMenu.Helpers return; } - if (!menuData.IsNetworkRoot && FolderOptions.IsHidden(rowData)) + if (!menuData.IsNetworkRoot) { - rowDatasToRemove.Add(rowData); - continue; + FolderOptions.ReadHiddenAttributes(rowData.Path, out bool hasHiddenFlag, out bool isDirectoryToHide); + if (isDirectoryToHide) + { + rowDatasToRemove.Add(rowData); + continue; + } + + rowData.HiddenEntry = hasHiddenFlag; } rowData.ReadIcon(true); diff --git a/Utilities/FolderOptions.cs b/Utilities/FolderOptions.cs index 6e85db7..937523a 100644 --- a/Utilities/FolderOptions.cs +++ b/Utilities/FolderOptions.cs @@ -1,93 +1,91 @@ -// -// Copyright (c) PlaceholderCompany. All rights reserved. -// - -namespace SystemTrayMenu.Utilities -{ - using System; - using System.IO; - using System.Reflection; - using System.Runtime.InteropServices; - using Shell32; - using SystemTrayMenu.DataClasses; - - internal static class FolderOptions - { - private static bool hideHiddenEntries; - private static bool hideSystemEntries; - private static IShellDispatch4? iShellDispatch4; - - internal static void Initialize() - { - try - { - iShellDispatch4 = (IShellDispatch4?)Activator.CreateInstance( - Type.GetTypeFromProgID("Shell.Application")!); - - // Using SHGetSetSettings would be much better in performance but the results are not accurate. - // We have to go for the shell interface in order to receive the correct settings: - // https://docs.microsoft.com/en-us/windows/win32/shell/ishelldispatch4-getsetting - const int SSF_SHOWALLOBJECTS = 0x00000001; - hideHiddenEntries = !(iShellDispatch4?.GetSetting(SSF_SHOWALLOBJECTS) ?? false); - - const int SSF_SHOWSUPERHIDDEN = 0x00040000; - hideSystemEntries = !(iShellDispatch4?.GetSetting(SSF_SHOWSUPERHIDDEN) ?? false); - } - catch (Exception ex) - { - if (ex is ArgumentException || - ex is NotSupportedException || - ex is TargetInvocationException || - ex is MethodAccessException || - ex is MemberAccessException || - ex is InvalidComObjectException || - ex is MissingMethodException || - ex is COMException || - ex is TypeLoadException) - { - Log.Warn("Get Shell COM instance failed", ex); - } - else - { - throw; - } - } - } - - internal static bool IsHidden(RowData rowData) - { - bool isDirectoryToHide = false; - if (rowData.Path == null || rowData.Path.Length >= 260) - { - Log.Info($"path too long (>=260):'{rowData.Path}'"); - return isDirectoryToHide; - } - - try - { - FileAttributes attributes = File.GetAttributes(rowData.Path); - rowData.HiddenEntry = attributes.HasFlag(FileAttributes.Hidden); - bool systemEntry = attributes.HasFlag( - FileAttributes.Hidden | FileAttributes.System); - if (Properties.Settings.Default.SystemSettingsShowHiddenFiles) - { - if ((hideHiddenEntries && rowData.HiddenEntry) || - (hideSystemEntries && systemEntry)) - { - isDirectoryToHide = true; - } - } - else if (rowData.HiddenEntry && Properties.Settings.Default.NeverShowHiddenFiles) - { - isDirectoryToHide = true; - } - } - catch (Exception ex) - { - Log.Warn($"path:'{rowData.Path}'", ex); - } - - return isDirectoryToHide; - } - } -} +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// + +namespace SystemTrayMenu.Utilities +{ + using System; + using System.IO; + using System.Reflection; + using System.Runtime.InteropServices; + using Shell32; + + internal static class FolderOptions + { + private static bool hideHiddenEntries; + private static bool hideSystemEntries; + private static IShellDispatch4? iShellDispatch4; + + internal static void Initialize() + { + try + { + iShellDispatch4 = (IShellDispatch4?)Activator.CreateInstance( + Type.GetTypeFromProgID("Shell.Application")!); + + // Using SHGetSetSettings would be much better in performance but the results are not accurate. + // We have to go for the shell interface in order to receive the correct settings: + // https://docs.microsoft.com/en-us/windows/win32/shell/ishelldispatch4-getsetting + const int SSF_SHOWALLOBJECTS = 0x00000001; + hideHiddenEntries = !(iShellDispatch4?.GetSetting(SSF_SHOWALLOBJECTS) ?? false); + + const int SSF_SHOWSUPERHIDDEN = 0x00040000; + hideSystemEntries = !(iShellDispatch4?.GetSetting(SSF_SHOWSUPERHIDDEN) ?? false); + } + catch (Exception ex) + { + if (ex is ArgumentException || + ex is NotSupportedException || + ex is TargetInvocationException || + ex is MethodAccessException || + ex is MemberAccessException || + ex is InvalidComObjectException || + ex is MissingMethodException || + ex is COMException || + ex is TypeLoadException) + { + Log.Warn("Get Shell COM instance failed", ex); + } + else + { + throw; + } + } + } + + internal static void ReadHiddenAttributes(string? path, out bool hasHiddenFlag, out bool isDirectoryToHide) + { + isDirectoryToHide = false; + hasHiddenFlag = false; + if (path == null || path.Length >= 260) + { + Log.Info($"path too long (>=260):'{path}'"); + return; + } + + try + { + FileAttributes attributes = File.GetAttributes(path); + hasHiddenFlag = attributes.HasFlag(FileAttributes.Hidden); + bool hasSystemFlag = attributes.HasFlag( + FileAttributes.Hidden | FileAttributes.System); + if (Properties.Settings.Default.SystemSettingsShowHiddenFiles) + { + if ((hideHiddenEntries && hasHiddenFlag) || + (hideSystemEntries && hasSystemFlag)) + { + isDirectoryToHide = true; + } + } + else if (hasHiddenFlag && Properties.Settings.Default.NeverShowHiddenFiles) + { + isDirectoryToHide = true; + } + } + catch (Exception ex) + { + Log.Warn($"path:'{path}'", ex); + } + } + } +}