Remove RowData dependency from FolderOptions

This commit is contained in:
Peter Kirmeier 2023-04-27 21:11:20 +02:00
parent 46bd18eb7e
commit 2e1cc20593
4 changed files with 106 additions and 106 deletions

View file

@ -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<RowData> rowDatas = new()

View file

@ -18,14 +18,6 @@ namespace SystemTrayMenu.DataClasses
{
private static DateTime contextMenuClosed;
/// <summary>
/// Initializes a new instance of the <see cref="RowData"/> class.
/// empty dummy.
/// </summary>
internal RowData()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RowData"/> class.
/// (Related replace "\x00" see #171.)

View file

@ -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);

View file

@ -1,93 +1,91 @@
// <copyright file="FolderOptions.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
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 file="FolderOptions.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
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);
}
}
}
}