8

I want to read the binary contents of a .lnk file. As long as the target of the shortcut (lnk file) exists this works fine with IO.File.ReadAllBytes(string file).

BUT

If the target of the shortcut does not exist (believe me I want this) the method only returns zero's. I guess this is because the OS follows the link and if it does not exist it returns zero's

Is there some way to bypass the fact that the framework follows the target of the .lnk before displaying the contents of the .lnk file?

Flores
  • 8,226
  • 5
  • 49
  • 81

3 Answers3

24

It doesn't make a lot of sense, don't have an easy way to check it. I reckon the best approach is to read the .lnk file the way it is supposed to be read. You can use COM to do so, the ShellLinkObject class implements the IShellLink interface. Get started with Project + Add Reference, Browse tab and navigate to c:\windows\system32\shell32.dll. That generates an interop library. Write code like this:

public static string GetLnkTarget(string lnkPath) {
    var shl = new Shell32.Shell();         // Move this to class scope
    lnkPath = System.IO.Path.GetFullPath(lnkPath);
    var dir = shl.NameSpace(System.IO.Path.GetDirectoryName(lnkPath));
    var itm = dir.Items().Item(System.IO.Path.GetFileName(lnkPath));
    var lnk = (Shell32.ShellLinkObject)itm.GetLink;
    return lnk.Target.Path;
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Nice snippet. BTW, when I used this I had to change the last line to return lnk.Target.Path. – Mr. Bungle Apr 17 '11 at 02:14
  • Actually, the last line should be return lnk.Path – Mark T Jun 20 '11 at 21:35
  • you also have to add Microsoft.Csharp assembly to avoid the Binder compile error, and instead of adding the shell32.dll you should select 'Microsoft Shell Controls And Automation' from the COM Type Libraries tab – dmihailescu Feb 19 '14 at 22:26
  • 1
    This appears to require an STA thread to run, which you get for free in a C# UI app, but have to create manually in a console app. Even then, I ran into errors on some machines that appear to relate to permissions to interact with the UI system. Console apps (including windows services) may not have permission to interact with UI. The lower-level IShellLink seems to avoid these issues of STA thread and permissions. See accepted answer here: http://stackoverflow.com/questions/139010/how-to-resolve-a-lnk-in-c-sharp – robertburke Feb 01 '17 at 00:33
  • I'm able to use this to read an .lnk file without utilizing a UI or other thread. – JSWulf Apr 19 '18 at 14:19
  • It is risky, older Windows versions don't behave well when you use this object on a non-STA thread. Win7 is the new XP. – Hans Passant Apr 19 '18 at 14:23
0

I don't believe ReadAllBytes induces the OS to follow the lnk to its target. I suspect, the OS has already resolved the lnk file (maybe when you browsed to the file in Windows Explorer).

logicnp
  • 5,796
  • 1
  • 28
  • 32
0

Turns out the file was locked because it was copied from another machine (i'm using server 2008 r2) unlocking it returned the behavoir to expected.

Stupid me.

Flores
  • 8,226
  • 5
  • 49
  • 81