diff --git a/Business/Menus.cs b/Business/Menus.cs index a40ddad..b5aa405 100644 --- a/Business/Menus.cs +++ b/Business/Menus.cs @@ -470,7 +470,7 @@ namespace SystemTrayMenu.Business RowData rowData = ReadRowData(directory, false, true); rowData.HiddenEntry = hiddenEntry; string resolvedLnkPath = string.Empty; - rowData.ReadIcon(true, ref resolvedLnkPath, level); + rowData.ReadIconOrResolveLinkAndReadIcon(true, ref resolvedLnkPath, level); rowData.MenuLevel = level; menuData.RowDatas.Add(rowData); } @@ -528,7 +528,7 @@ namespace SystemTrayMenu.Business } string resolvedLnkPath = string.Empty; - if (rowData.ReadIcon(false, ref resolvedLnkPath, level)) + if (rowData.ReadIconOrResolveLinkAndReadIcon(false, ref resolvedLnkPath, level)) { rowData = ReadRowData(resolvedLnkPath, true, true, rowData); rowData.HiddenEntry = hiddenEntry; diff --git a/Config/Config.cs b/Config/Config.cs index 4ea5bd3..22efa26 100644 --- a/Config/Config.cs +++ b/Config/Config.cs @@ -19,7 +19,7 @@ namespace SystemTrayMenu { private static readonly Icon SystemTrayMenu = Properties.Resources.SystemTrayMenu; private static readonly Icon IconFromRootFolder = IconReader.GetIconSTA( - Path, false, IconReader.IconSize.Small, IconReader.FolderType.Closed); + Path, Path, false, IconReader.IconSize.Small, IconReader.FolderType.Closed); private static bool readDarkModeDone; private static bool isDarkMode; diff --git a/DataClasses/RowData.cs b/DataClasses/RowData.cs index 4dc2673..d130c4e 100644 --- a/DataClasses/RowData.cs +++ b/DataClasses/RowData.cs @@ -81,7 +81,7 @@ namespace SystemTrayMenu.DataClasses row[2] = data; } - internal bool ReadIcon(bool isDirectory, ref string resolvedLnkPath, int level) + internal bool ReadIconOrResolveLinkAndReadIcon(bool isDirectory, ref string resolvedLnkPath, int level) { bool isLnkDirectory = false; @@ -108,7 +108,7 @@ namespace SystemTrayMenu.DataClasses if (fileExtension.Equals(".lnk", StringComparison.InvariantCultureIgnoreCase)) { - handled = SetLnk(level, ref isLnkDirectory, ref resolvedLnkPath); + handled = ResolveLinkAndReadIcon(level, ref isLnkDirectory, ref resolvedLnkPath); showOverlay = Properties.Settings.Default.ShowLinkOverlay; } else if (fileExtension.Equals(".url", StringComparison.InvariantCultureIgnoreCase)) @@ -116,10 +116,6 @@ namespace SystemTrayMenu.DataClasses SetText($"{FileInfo.Name[0..^4]}"); showOverlay = Properties.Settings.Default.ShowLinkOverlay; } - else if (fileExtension.Equals(".sln", StringComparison.InvariantCultureIgnoreCase)) - { - handled = SetSln(level); - } else if (fileExtension.Equals(".appref-ms", StringComparison.InvariantCultureIgnoreCase)) { showOverlay = Properties.Settings.Default.ShowLinkOverlay; @@ -127,21 +123,14 @@ namespace SystemTrayMenu.DataClasses if (!handled) { - try - { - FilePathIcon = TargetFilePathOrig; - icon = IconReader.GetFileIconWithCache( - FilePathIcon, - showOverlay, - true, - level == 0, - out bool loading); - IconLoading = loading; - } - catch (Exception ex) - { - Log.Warn($"path:'{TargetFilePathOrig}'", ex); - } + icon = IconReader.GetFileIconWithCache( + TargetFilePathOrig, + TargetFilePath, + showOverlay, + true, + level == 0, + out bool loading); + IconLoading = loading; } } @@ -250,20 +239,15 @@ namespace SystemTrayMenu.DataClasses else { bool showOverlay = false; - string fileExtension = Path.GetExtension(TargetFilePath); + string fileExtension = Path.GetExtension(TargetFilePathOrig); if (fileExtension == ".lnk" || fileExtension == ".url" || fileExtension == ".appref-ms") { showOverlay = Properties.Settings.Default.ShowLinkOverlay; } - string filePath = FilePathIcon; - if (string.IsNullOrEmpty(filePath)) - { - filePath = TargetFilePathOrig; - } - icon = IconReader.GetFileIconWithCache( - filePath, + TargetFilePathOrig, + TargetFilePath, showOverlay, false, MenuLevel == 0, @@ -299,7 +283,7 @@ namespace SystemTrayMenu.DataClasses } } - private bool SetLnk(int level, ref bool isLnkDirectory, ref string resolvedLnkPath) + private bool ResolveLinkAndReadIcon(int level, ref bool isLnkDirectory, ref string resolvedLnkPath) { bool handled = false; resolvedLnkPath = FileLnk.GetResolvedFileName(TargetFilePath, out bool isFolder); @@ -334,26 +318,5 @@ namespace SystemTrayMenu.DataClasses return handled; } - - private bool SetSln(int level) - { - bool handled = false; - try - { - icon = IconReader.GetExtractAllIconsLastWithCache( - TargetFilePathOrig, - true, - level == 0, - out bool loading); - IconLoading = loading; - handled = true; - } - catch (Exception ex) - { - Log.Warn($"path:'{TargetFilePath}'", ex); - } - - return handled; - } } } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 7ad9b8d..1b3c73e 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -39,5 +39,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.9.15")] -[assembly: AssemblyFileVersion("1.2.9.15")] +[assembly: AssemblyVersion("1.2.9.16")] +[assembly: AssemblyFileVersion("1.2.9.16")] diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index 3059eaf..79f4986 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -120,6 +120,16 @@ namespace SystemTrayMenu.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + public static System.Drawing.Icon LinkArrow { + get { + object obj = ResourceManager.GetObject("LinkArrow", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// diff --git a/Properties/Resources.resx b/Properties/Resources.resx index f576e12..4b3f22f 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -112,12 +112,12 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + ..\Resources\White50Percentage.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -148,4 +148,7 @@ ..\Resources\ic_fluent_settings_28_regular.svg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\LinkArrow.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Resources/LinkArrow.ico b/Resources/LinkArrow.ico new file mode 100644 index 0000000..faa4e64 Binary files /dev/null and b/Resources/LinkArrow.ico differ diff --git a/SystemTrayMenu.csproj b/SystemTrayMenu.csproj index c8e8b85..053130a 100644 --- a/SystemTrayMenu.csproj +++ b/SystemTrayMenu.csproj @@ -110,10 +110,6 @@ False ThirdParty\Clearcove.Logging.dll - - False - ThirdParty\TAFactory.IconPack.dll - diff --git a/Utilities/File/IconReader.cs b/Utilities/File/IconReader.cs index 0b6556b..16b9919 100644 --- a/Utilities/File/IconReader.cs +++ b/Utilities/File/IconReader.cs @@ -16,7 +16,6 @@ namespace SystemTrayMenu.Utilities using System.Text; using System.Threading; using SystemTrayMenu.DllImports; - using TAFactory.IconPack; /// /// Provides static methods to read system icons for folders and files. @@ -70,80 +69,9 @@ namespace SystemTrayMenu.Utilities return cleared; } - public static Icon GetExtractAllIconsLastWithCache( - string filePath, - bool updateIconInBackground, - bool isMainMenu, - out bool loading) - { - bool linkOverlay = false; - loading = false; - string key = filePath; - - string extension = Path.GetExtension(filePath); - - if (IsExtensionWithSameIcon(extension)) - { - key = extension + linkOverlay; - } - - if (!DictIconCache(isMainMenu).TryGetValue(key, out Icon icon) && - !DictIconCache(!isMainMenu).TryGetValue(key, out icon)) - { - icon = Resources.StaticResources.LoadingIcon; - loading = true; - - if (updateIconInBackground) - { - new Thread(UpdateIconInBackground).Start(); - void UpdateIconInBackground() - { - DictIconCache(isMainMenu).GetOrAdd(key, GetExtractAllIconsLastSTA(filePath)); - } - } - } - - static Icon GetExtractAllIconsLastSTA(string filePath) - { - Icon icon = null; - - if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) - { - icon = GetExtractAllIconsLast(filePath); - } - else - { - Thread staThread = new(new ParameterizedThreadStart(StaThreadMethod)); - void StaThreadMethod(object obj) - { - icon = GetExtractAllIconsLast(filePath); - } - - staThread.SetApartmentState(ApartmentState.STA); - staThread.Start(icon); - staThread.Join(); - } - - static Icon GetExtractAllIconsLast(string filePath) - { - StringBuilder executable = new(1024); - NativeMethods.Shell32FindExecutable(filePath, string.Empty, executable); - - // icon = IconReader.GetFileIcon(executable, false); - // e.g. VS 2019 icon, need another icom in imagelist - List extractedIcons = IconHelper.ExtractAllIcons( - executable.ToString()); - return extractedIcons.Last(); - } - - return icon; - } - - return icon; - } - public static Icon GetFileIconWithCache( - string filePath, + string pathOrig, + string path, bool linkOverlay, bool updateIconInBackground, bool isMainMenu, @@ -151,10 +79,10 @@ namespace SystemTrayMenu.Utilities string keyPath = "") { loading = false; - string extension = Path.GetExtension(filePath); + string extension = Path.GetExtension(pathOrig); IconSize size = IconSize.Large; - string key = filePath; + string key = pathOrig; if (!string.IsNullOrEmpty(keyPath)) { key = keyPath; @@ -175,7 +103,7 @@ namespace SystemTrayMenu.Utilities new Thread(UpdateIconInBackground).Start(); void UpdateIconInBackground() { - DictIconCache(isMainMenu).GetOrAdd(key, GetIconSTA(filePath, linkOverlay, size, null)); + DictIconCache(isMainMenu).GetOrAdd(key, GetIconSTA(pathOrig, path, linkOverlay, size, null)); } } } @@ -228,25 +156,25 @@ namespace SystemTrayMenu.Utilities Icon GetFolder(string keyExtension) { - return GetIconSTA(path, linkOverlay, size, folderType); + return GetIconSTA(path, path, linkOverlay, size, folderType); } return icon; } - public static Icon GetIconSTA(string path, bool linkOverlay, IconSize size, FolderType? folderType) + public static Icon GetIconSTA(string pathOrig, string path, bool linkOverlay, IconSize size, FolderType? folderType) { Icon icon = null; if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) { - icon = GetIcon(path, linkOverlay, size, folderType); + icon = GetIcon(pathOrig, path, linkOverlay, size, folderType); } else { Thread staThread = new(new ParameterizedThreadStart(StaThreadMethod)); void StaThreadMethod(object obj) { - icon = GetIcon(path, linkOverlay, size, folderType); + icon = GetIcon(pathOrig, path, linkOverlay, size, folderType); } staThread.SetApartmentState(ApartmentState.STA); @@ -299,15 +227,34 @@ namespace SystemTrayMenu.Utilities return isExtensionWithSameIcon; } - private static Icon GetIcon(string path, bool linkOverlay, IconSize size, FolderType? type) + private static Icon GetIcon(string path, string pathOrig, bool linkOverlay, IconSize size, FolderType? type) { - NativeMethods.SHFILEINFO shFileInfo = default; - uint flags = GetFlags(linkOverlay, size, type); - uint attribute = type == null ? NativeMethods.FileAttributeNormal : - NativeMethods.FileAttributeDirectory; - IntPtr imageList = NativeMethods.Shell32SHGetFileInfo( - path, attribute, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), flags); - return GetIcon(path, linkOverlay, shFileInfo, imageList); + Icon icon; + if (Path.GetExtension(path).Equals(".ico", StringComparison.InvariantCultureIgnoreCase)) + { + icon = Icon.ExtractAssociatedIcon(path); + } + else if (Path.GetExtension(pathOrig).Equals(".ico", StringComparison.InvariantCultureIgnoreCase) && + File.Exists(pathOrig)) + { + icon = Icon.ExtractAssociatedIcon(pathOrig); + if (linkOverlay) + { + icon = AddIconOverlay(icon, Properties.Resources.LinkArrow); + } + } + else + { + NativeMethods.SHFILEINFO shFileInfo = default; + uint flags = GetFlags(linkOverlay, size, type); + uint attribute = type == null ? NativeMethods.FileAttributeNormal : + NativeMethods.FileAttributeDirectory; + IntPtr imageList = NativeMethods.Shell32SHGetFileInfo( + path, attribute, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), flags); + icon = GetIcon(path, linkOverlay, shFileInfo, imageList); + } + + return icon; } private static uint GetFlags(bool linkOverlay, IconSize size, FolderType? folderType)