diff --git a/src/modules/peek/Peek.Common/Helpers/SymlinkResolver.cs b/src/modules/peek/Peek.Common/Helpers/SymlinkResolver.cs new file mode 100644 index 0000000000..96073cd9ad --- /dev/null +++ b/src/modules/peek/Peek.Common/Helpers/SymlinkResolver.cs @@ -0,0 +1,80 @@ +// PeekSymlinkResolver.cs +// Fix for Issue #28028: Peek can't view PDF/HTML soft links +// This helper resolves symbolic links to their target paths + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace Peek.Common.Helpers +{ + /// + /// Resolves symbolic links and junction points to their target paths. + /// + public static class SymlinkResolver + { + /// + /// Resolves a path to its final target if it's a symbolic link or junction. + /// + /// The path to resolve. + /// The resolved target path, or the original path if not a link. + public static string ResolveSymlink(string path) + { + if (string.IsNullOrEmpty(path)) + { + return path; + } + + try + { + var fileInfo = new FileInfo(path); + + // Check if it's a symbolic link + if (fileInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) + { + // Get the target of the symbolic link + var target = fileInfo.LinkTarget; + if (!string.IsNullOrEmpty(target)) + { + // If target is relative, make it absolute + if (!Path.IsPathRooted(target)) + { + var directory = Path.GetDirectoryName(path); + target = Path.GetFullPath(Path.Combine(directory ?? string.Empty, target)); + } + + return target; + } + } + + return path; + } + catch (Exception) + { + // If resolution fails, return the original path + return path; + } + } + + /// + /// Checks if a path is a symbolic link or junction point. + /// + public static bool IsSymlink(string path) + { + if (string.IsNullOrEmpty(path) || !File.Exists(path)) + { + return false; + } + + try + { + var attributes = File.GetAttributes(path); + return attributes.HasFlag(FileAttributes.ReparsePoint); + } + catch + { + return false; + } + } + } +}