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;
+ }
+ }
+ }
+}