C#读取快捷方式(.lnk)文件 C#如何解析快捷方式指向的真实路径

来源:这里教程网 时间:2026-02-21 17:42:20 作者:

为什么
File.Exists
对 .lnk 文件返回 false?

因为 .lnk 是 Windows Shell 的二进制封装格式,不是普通文件。C# 原生的

File
Path
类完全不识别它——直接传入
.lnk
路径调用
File.Exists
new FileInfo()
,结果必然是
false
或抛出
FileNotFoundException
。必须用 Windows Shell 接口解析其内部的“目标路径”字段。

ShellLinkObject
(Windows Script Host)最轻量

无需引用 COM 组件或安装 SDK,只要系统有 WSH(所有 Windows 默认自带),就能通过

IWshShell
IWshShortcut
读取。注意:仅限桌面应用(.NET Framework / .NET Core/.NET 5+ Windows 桌面运行时),不适用于纯跨平台或 ASP.NET Core Web 应用。

实操步骤:

添加 COM 引用:
Windows Script Host Object Model
(在 Visual Studio “添加引用 → COM → 类型库”中找)
或使用
tlbimp
手动导入,生成
IWshRuntimeLibrary.dll
代码中用
dynamic
或强类型调用,例如:
var wsh = new IWshShell_Class();
var shortcut = (IWshShortcut)wsh.CreateShortcut(@"C:\path\to\file.lnk");
string targetPath = shortcut.TargetPath; // 真实路径(可能为空、相对、UNC 或环境变量)

⚠️ 注意:

TargetPath
可能含
%USERPROFILE%
等变量,需用
Environment.ExpandEnvironmentVariables()
;若为相对路径,要结合
shortcut.WorkingDirectory
解析。

IShellLink
(COM 接口)更底层、更可靠

绕过 WSH 层,直连 Windows Shell 的

IShellLink
,支持所有快捷方式特性(如 AppUserModelId、网络驱动器映射、Unicode 路径)。但必须手动 P/Invoke 或用 NuGet 包封装。

推荐使用开源库

ManagedShell
(NuGet:
ManagedShell.Common
):

using ManagedShell.Common.Helpers;
var link = new ShellLinkHelper();
string target = link.ResolveShortcut(@"C:\test.lnk");

或手写 COM 调用(需

[ComImport]
Guid
CoCreateInstance
),容易出内存泄漏或线程套间(STA)错误。常见坑:

必须在 STA 线程运行(Main 方法加
[STAThread]
未调用
IPersistFile.Load()
就读
GetPath()
→ 返回空字符串
路径含中文或长路径时,未启用
lpFile
缓冲区足够大 → 截断

解析失败时的典型现象和对策

快捷方式可能损坏、指向已删除路径、跨卷/网络/OneDrive 同步状态异常,导致解析返回空或错误路径。

检查顺序建议:

先确认
.lnk
文件存在且可读(
File.GetAttributes()
不抛异常)
读出
TargetPath
后,用
Path.IsPathRooted()
判断是否绝对;否则拼接
WorkingDirectory
调用
Environment.ExpandEnvironmentVariables()
处理变量
最后用
File.Exists()
Directory.Exists()
验证目标是否存在——这才是真正有效的“存在性判断”

特别注意:某些企业环境禁用 WSH(组策略关闭

WScript.exe
),此时
ShellLinkObject
方式会静默失败,必须 fallback 到
IShellLink
P/Invoke 实现。

相关推荐