3

Several frameworks and languages seem to have lnk file parsers (C#, Java, Python, certainly countless others), to get to their targets, properties, etc. I'd like to know what is the general approach to reading lnk files, if I want to parse the lnk in another language that does not have said feature. Is there a Windows API for this?

MPelletier
  • 16,256
  • 15
  • 86
  • 137

4 Answers4

2

Simply use lnk file parser at J.A.F.A.T. Archive of Forensics Analysis Tools project.

See lnk-parse-1.0.pl at http://jafat.sourceforge.net

There seems no have no dependencies. Syntax is simple and link file becomes a simple text in standard output and to be usable on Linux.

MUY Belgium
  • 2,330
  • 4
  • 30
  • 46
1

@Giorgi: Actually, there is an official specification of lnk files, at least it is claimed so. However, for some reason, the link seems to be dead, and after downloading the whole (45 MB) doc package (Application_Services_and_NET_Framework.zip), it appears that it does not include the file MS-SHLLINK.pdf.

But is this really surprising ?

Once you got the file format, shouldn't be too hard to write code to read it.

Cadoiz
  • 1,446
  • 21
  • 31
kebs
  • 6,387
  • 4
  • 41
  • 70
  • 1
    Now this is here: https://msdn.microsoft.com/en-us/library/dd871305.aspx?f=255&MSPPError=-2147217396 . – deerchao May 13 '16 at 06:31
0

here's some C# code using the Shell32 API, from my "ClearRecentLinks" project at https://github.com/jmaton/ClearRecentLinks

To use this your C# project has to reference c:\windows\system32\shell32.dll

            string linksPath = "c:\some\folder";
            Type shell32Type = Type.GetTypeFromProgID("Shell.Application");
            Object shell = Activator.CreateInstance(shell32Type);
            Shell32.Folder s32Folder = (Shell32.Folder)shell32Type.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { linksPath });
            foreach (Shell32.FolderItem2 item in s32Folder.Items())
            {
                if (item.IsLink)
                {
                    var link = (Shell32.ShellLinkObject)item.GetLink;
                    if (link != null && !String.IsNullOrEmpty(link.Target.Path))
                    {
                        string linkTarget = link.Target.Path.ToLower();
                        // do something... 
                    }
                }
            }
Jay
  • 173
  • 1
  • 7
0

Using WSH-related components seems the most convenient option to read .lnk files in most languages on a post-XP windows system. You just need access to the COM environment and instantiate the WScript.Shell Component. (remember that on win, references to the Shell usually refer to explorer.exe)

The following snippet, e.g. does the thing on PHP: (PHP 5, using the COM object)

<?php
$wsh=new COM('WScript.Shell'); // the wsh object

// please note $wsh->CreateShortcut method actually
// DOES THE READING, if the file already exists. 
$lnk=$wsh->CreateShortcut('./Shortcut.lnk');
echo $lnk->TargetPath,"\n";

This other one, instead, does the same on VBScript:

set sh = WScript.CreateObject("WScript.Shell")
set lnk = sh.CreateShortcut("./Shortcut.lnk")
MsgBox lnk.TargetPath

Most examples in the field are written in VB/VBS, but they translate well on the whole range of languages supporting COM and WSH interaction in a form or another.

This simple tutorial may come handy, as it lists and exemplifies some of the most interesting properties of a .lnk file other than the most important: TargetPath. Those are:

  • WindowStyle,
  • Hotkey,
  • IconLocation,
  • Description,
  • WorkingDirectory
ZJR
  • 9,308
  • 5
  • 31
  • 38