必须引用Windows Script Host Object Model才能用C#创建快捷方式,因原生类库不支持.lnk文件操作;应使用IWshShortcut而非IShellLink,修改时须先Load()再Save()。

用 ShellLink 创建快捷方式必须引用 Windows Script Host Object Model
直接用 C# 原生类库没法创建或修改 .lnk 文件,得靠 COM 组件 WScript.Shell。不加引用会编译报错:COMException: 检索 COM 类工厂中 CLSID 为 {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} 的组件时失败。
操作步骤:
- 在项目中右键「引用」→「添加 COM 引用」→ 找到
Windows Script Host Object Model(对应类型库IWshRuntimeLibrary) - 或者用
dotnet add reference命令(.NET SDK 6+):dotnet add reference /path/to/IWshRuntimeLibrary.dll(实际路径需查注册表或用 OLE/COM 对象查看器定位) - 代码里用
using IWshRuntimeLibrary;,别写成System.Runtime.InteropServices—— 后者只是辅助,不是替代
IShellLink 和 IWshShortcut 别混用
IShellLink 是 Windows Shell API 的原生接口,C# 调用它需要手动 Marshal、处理 IPersistFile,极易内存泄漏或 COM 释放失败;而 IWshShortcut 是 WSH 封装好的高层对象,简单安全得多。
推荐只用 IWshShortcut,除非你明确需要自定义图标索引、工作目录继承行为或解析网络路径的特殊逻辑。
典型错误:看到 MSDN 示例用 IShellLink 就照搬,结果在 .NET 5+ 上抛 InvalidCastException 或静默失败——因为 CoCreateInstance 返回的对象类型和接口 QI 不匹配。
正确写法示例:
IWshShell shell = new WshShell(); IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(@"C:\Users\Public\Desktop\MyApp.lnk"); shortcut.TargetPath = @"C:\Program Files\MyApp\app.exe"; shortcut.WorkingDirectory = @"C:\Program Files\MyApp"; shortcut.Description = "Launch MyApp"; shortcut.Save();
修改已存在快捷方式要先 Load(),否则属性全丢
直接 new 一个 IWshShortcut 并赋值再 Save(),只会覆盖原文件、清空所有原有属性(比如图标路径、参数、快捷键),而不是“更新”。
必须显式调用 Load() 加载已有 .lnk 文件内容:
-
shortcut.Load(@"C:\path\to\existing.lnk")—— 这步不能省,且路径必须存在,否则抛FileNotFoundException - 加载后才能安全改
Arguments、Hotkey、IconLocation等字段 -
IconLocation格式是"path,icon_index"(如"shell32.dll,12"),单独给路径不生效
常见坑:Hotkey 必须是字符串格式,比如 "Ctrl+Alt+T",写成 Keys.Control | Keys.Alt | Keys.T 会静默忽略。
桌面路径别硬编码,用 Environment.GetFolderPath
写死 C:\Users\XXX\Desktop 在多用户、域环境、OneDrive 同步桌面或非英文系统下必然出错。
正确做法是动态获取:
- 当前用户桌面:
Environment.GetFolderPath(Environment.SpecialFolder.Desktop) - 公共桌面(所有用户可见):
Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory) - 注意:后者需要管理员权限才能写入,否则
Save()抛UnauthorizedAccessException
另外,目标路径(TargetPath)如果含空格或 Unicode 字符,不用额外转义 —— IWshShortcut 内部已处理,但确保路径真实存在,否则快捷方式变成“找不到目标”状态。
真正麻烦的是跨架构(x86/x64)调用:32 位进程在 64 位系统上调 WScript.Shell,可能被重定向到 SysWOW64 下的组件,导致某些旧版系统上 CreateShortcut 返回 null。最稳的方式是统一编译为 x64 或 AnyCPU 并勾选 Prefer 32-bit(仅限 .NET Framework)。










