4

Other solutions for viewing the target of a .lnk file requires the use of .NET Framework. I would like to read the target of a .lnk file from .NET Core without using an interop to .NET Framework (specifically the Shell32.Shell method). If there are any solutions that do not require third party libraries, I would prefer to use those if possible. However, I was unable to find the answer in the .NET Core standard library.

GLJ
  • 1,074
  • 1
  • 9
  • 17

2 Answers2

9

Using a solution I found that was implemented in Python, I rewrote the function in C#.

https://stackoverflow.com/a/28952464/11530367

public static string GetLnkTargetPath(string filepath)
{
    using (var br = new BinaryReader(System.IO.File.OpenRead(filepath)))
    {
        // skip the first 20 bytes (HeaderSize and LinkCLSID)
        br.ReadBytes(0x14);
        // read the LinkFlags structure (4 bytes)
        uint lflags = br.ReadUInt32();
        // if the HasLinkTargetIDList bit is set then skip the stored IDList 
        // structure and header
        if ((lflags & 0x01) == 1)
        {
            br.ReadBytes(0x34);
            var skip = br.ReadUInt16(); // this counts of how far we need to skip ahead
            br.ReadBytes(skip);
        }
        // get the number of bytes the path contains
        var length = br.ReadUInt32();
        // skip 12 bytes (LinkInfoHeaderSize, LinkInfoFlgas, and VolumeIDOffset)
        br.ReadBytes(0x0C);
        // Find the location of the LocalBasePath position
        var lbpos = br.ReadUInt32();
        // Skip to the path position 
        // (subtract the length of the read (4 bytes), the length of the skip (12 bytes), and
        // the length of the lbpos read (4 bytes) from the lbpos)
        br.ReadBytes((int)lbpos - 0x14);
        var size = length - lbpos - 0x02;
        var bytePath = br.ReadBytes((int)size);
        var path = Encoding.UTF8.GetString(bytePath, 0, bytePath.Length);
        return path;
    }
}
GLJ
  • 1,074
  • 1
  • 9
  • 17
  • Perhaps test for 0 length in bytePath.Length to see if the .lnk file is bad: var path = Encoding.UTF8.GetString(bytePath, 0, bytePath.Length); if so I would return null or string.empty – Walter Verhoeven Aug 09 '23 at 08:29
1

This library is able to read all the data from an lnk file: https://github.com/sailro/Shellify

var linkFile = Shellify.ShellLinkFile.Load(linkPath);
var linkTarget = Path.Combine(linkFile.LinkInfo.CommonNetworkRelativeLink.NetName, linkFile.LinkInfo.CommonPathSuffix);
innominate227
  • 11,109
  • 1
  • 17
  • 20