C# WinUI3应用如何通过代码创建快捷方式?SetPath应传入什么?
解决WinUI 3 MSIX应用代码创建快捷方式的问题
WinUI 3应用打包为MSIX后,无法通过传统的IShellLink指向exe/dll的方式创建有效快捷方式,因为MSIX应用是通过Windows应用模型的包标识符+入口点启动的,而非直接执行可执行文件。以下是正确的实现方案:
核心思路
创建的快捷方式需要指向MSIX应用的特殊启动路径格式:shell:AppsFolder\<PackageFamilyName>!<EntryPointId>,该路径会引导系统正确唤起对应的MSIX应用。
完整代码实现
1. 定义必要的COM接口
首先需要引入ShellLink相关的COM接口定义(用于操作快捷文件):
using System; using System.IO; using System.Runtime.InteropServices; using Windows.ApplicationModel; [ComImport] [Guid("00021401-0000-0000-C000-000000000046")] internal class ShellLink { } [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("000214F9-0000-0000-C000-000000000046")] internal interface IShellLink { void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, uint fFlags); void GetIDList(out IntPtr ppidl); void SetIDList(IntPtr pidl); void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); void GetHotkey(out short pwHotkey); void SetHotkey(short wHotkey); void GetShowCmd(out int piShowCmd); void SetShowCmd(int iShowCmd); void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon); void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved); void Resolve(IntPtr hwnd, uint fFlags); void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); } [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("0000010b-0000-0000-C000-000000000046")] internal interface IPersistFile { void GetClassID(out Guid pClassID); int IsDirty(); void Load([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode); void Save([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, [MarshalAs(UnmanagedType.Bool)] bool fRemember); void SaveCompleted([MarshalAs(UnmanagedType.LPWStr)] string pszFileName); void GetCurFile([MarshalAs(UnmanagedType.LPWStr)] out string ppszFileName); }
2. 编写创建快捷方式的方法
private static void CreateWinUI3Shortcut() { // 获取当前MSIX包的核心信息 var package = Package.Current; var packageFamilyName = package.Id.FamilyName; // 入口点ID:对应Package.appxmanifest中Application元素的Id属性,默认值为"App" var entryPointId = "App"; // 构造MSIX应用的特殊启动路径 var appLaunchPath = $"shell:AppsFolder\\{packageFamilyName}!{entryPointId}"; IShellLink link = (IShellLink)new ShellLink(); // 配置快捷方式属性 link.SetDescription("我的WinUI3应用快捷方式"); // 设置启动路径为MSIX应用的特殊路径 link.SetPath(appLaunchPath); // 可选:设置快捷方式图标(从应用包的Assets目录获取) var iconPath = Path.Combine(package.InstalledLocation.Path, "Assets", "Logo.png"); link.SetIconLocation(iconPath, 0); // 保存快捷方式到桌面 IPersistFile file = (IPersistFile)link; string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); file.Save(Path.Combine(desktopPath, "我的WinUI3应用.lnk"), false); }
关键说明
- 入口点ID确认:打开项目的
Package.appxmanifest文件,查看<Application>元素的Id属性值,将其替换代码中的entryPointId。 - 权限注意:MSIX应用默认允许访问用户桌面目录,无需额外声明特殊权限即可写入快捷方式。
- 传统方法失效原因:WinUI3打包为MSIX后,应用的可执行文件被封装在只读的WindowsApps目录中,系统通过应用模型而非直接执行exe启动应用,因此指向dll/exe的快捷方式无法正常唤起应用。
内容的提问来源于stack exchange,提问作者7Mircea
相关产品推荐
相关产品推荐

