.NET读取.lnk文件的二进制内容

8
我想读取一个.lnk文件的二进制内容。只要快捷方式(lnk文件)的目标存在,使用IO.File.ReadAllBytes(string file)就可以正常工作。
但是,
如果快捷方式的目标不存在(相信我,我希望它不存在),该方法仅返回零。我猜这是因为操作系统会跟随链接,如果链接不存在,则返回零。
有没有办法绕过框架在显示.lnk文件内容之前遵循目标的事实?
3个回答

24

这不太有意义,没有简单的方式来检查它。我认为最好的方法是按照它应该被读取的方式来读取.lnk文件。您可以使用COM这样做,ShellLinkObject类 实现了IShellLink接口。使用Project + Add Reference, Browse选项卡并导航到c:\windows\system32\shell32.dll开始。这将生成一个Interop库。编写如下代码:

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

不错的代码片段。顺便说一下,当我使用它时,我不得不将最后一行更改为 return lnk.Target.Path。 - Mr. Bungle
实际上,最后一行应该是 return lnk.Path。 - Mark T
你还需要添加Microsoft.Csharp程序集以避免Binder编译错误,而不是添加shell32.dll,你应该从COM类型库选项卡中选择“Microsoft Shell Controls And Automation”。 - dmihailescu
1
这似乎需要一个STA线程来运行,在C# UI应用程序中可以免费获得,但在控制台应用程序中必须手动创建。即使如此,在某些机器上我遇到了与与UI系统交互的权限相关的错误。控制台应用程序(包括Windows服务)可能没有与UI交互的权限。较低级别的IShellLink似乎避免了这些STA线程和权限问题。请参见此处的已接受答案:https://dev59.com/s3VC5IYBdhLWcg3w9F89 - robertburke
我能够使用这个来读取.lnk文件,而不需要使用UI或其他线程。 - JSWulf
这是有风险的,旧版本的 Windows 在非 STA 线程上使用此对象时表现不佳。Win7 是新的 XP。 - Hans Passant

0

我不相信ReadAllBytes会导致操作系统跟随lnk到达其目标。我怀疑,在您使用Windows资源管理器浏览文件时,操作系统已经解析了lnk文件。


这是来自另一台计算机的广告快捷方式,因此该链接永远无法解析。 - Flores

0
原来文件被锁定是因为它是从另一台机器复制过来的(我正在使用服务器2008 r2),解锁后,行为恢复正常。
真是太蠢了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接