.NET 9 MAUI Windows应用创建桌面快捷方式的新方法咨询
在.NET 9 MAUI Windows应用中创建桌面快捷方式的解决方案
问题根源
原代码依赖的Shell32 COM组件在.NET 9 MAUI环境下兼容性不足,即便添加COM引用也无法正常调用CreateShortcut方法——这是因为MAUI的跨平台项目结构对COM组件的使用存在限制。
方案1:基于IWshRuntimeLibrary实现(简单易上手)
这是依赖COM组件的替代方案,实现成本较低:
- 安装依赖包:添加
Microsoft.VisualBasicNuGet包(内部封装了对IWshRuntimeLibrary的调用) - 编写平台专属代码:
#if WINDOWS using IWshRuntimeLibrary; using System.IO; public static void CreateDesktopShortcut() { string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); string shortcutPath = Path.Combine(desktopPath, "thing.lnk"); var wshShell = new WshShell(); var shortcut = (IWshShortcut)wshShell.CreateShortcut(shortcutPath); // 获取当前MAUI应用的可执行文件路径 shortcut.TargetPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; shortcut.Description = "interesting description"; // 可选:设置快捷方式图标路径 // shortcut.IconLocation = Path.Combine(AppContext.BaseDirectory, "AppIcon.ico"); shortcut.Save(); } #endif
- 关键提示:用
#if WINDOWS条件编译包裹代码,避免跨平台编译错误。
方案2:通过P/Invoke调用Windows原生Shell API(无COM依赖)
若不想依赖COM组件,可直接调用Windows底层API实现:
#if WINDOWS using System; using System.IO; using System.Runtime.InteropServices; public static class ShortcutCreator { [ComImport] [Guid("00021401-0000-0000-C000-000000000046")] private class ShellLink { } [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("000214F9-0000-0000-C000-000000000046")] private interface IShellLinkW { 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 ushort pwHotkey); void SetHotkey(ushort 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")] private 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); } public static void CreateDesktopShortcut() { string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); string shortcutPath = Path.Combine(desktopPath, "thing.lnk"); var shellLink = (IShellLinkW)new ShellLink(); shellLink.SetPath(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); shellLink.SetDescription("interesting description"); // 保存快捷方式到本地 var persistFile = (IPersistFile)shellLink; persistFile.Save(shortcutPath, false); } } #endif
MSIX打包应用的特殊处理
若你的MAUI应用是通过MSIX打包发布的,需遵循Windows应用商店的规范,通过系统API注册快捷方式,而非直接生成.lnk文件:
#if WINDOWS using Windows.ApplicationModel; using Windows.ApplicationModel.Shortcuts; public static async Task CreateDesktopShortcutForMsix() { var shortcut = new ShortcutInfo( id: "MyAppShortcut", displayName: "My MAUI App", description: "interesting description", targetActivationArguments: "", targetProtocol: new Uri($"ms-appx://{Package.Current.Id.FamilyName}/MainWindow.xaml") ); shortcut.Icon = new Uri($"ms-appx:///Assets/AppIcon.ico"); await ShortcutManager.GetDefault().CreateShortcutAsync(shortcut); } #endif
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

