You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 9 MAUI Windows应用创建桌面快捷方式的新方法咨询

在.NET 9 MAUI Windows应用中创建桌面快捷方式的解决方案

问题根源

原代码依赖的Shell32 COM组件在.NET 9 MAUI环境下兼容性不足,即便添加COM引用也无法正常调用CreateShortcut方法——这是因为MAUI的跨平台项目结构对COM组件的使用存在限制。

方案1:基于IWshRuntimeLibrary实现(简单易上手)

这是依赖COM组件的替代方案,实现成本较低:

  1. 安装依赖包:添加Microsoft.VisualBasic NuGet包(内部封装了对IWshRuntimeLibrary的调用)
  2. 编写平台专属代码:
#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
  1. 关键提示:用#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:50:15