How to create a shortcut for Store app on desktop?

Heiko 1,216 Reputation points
2023-01-21T13:49:11.01+00:00

I know that I can create a shortcut for a Store app with 'explorer.exe' and 'shell:AppsFolder<AppUserModelId>' as argument, but then I have the explorer icon. If I set the icon to the AppInfo.Package.Logo.AbsolutPath, I have an empty white icon in shortcut, but not the app icon. If I open 'shell:AppsFolder' in explorer, I can create a desktop shortcut via contextmenu on an app. How can I create a desktop shortcut with the right icon programmatically in a WPF app?

Universal Windows Platform (UWP)
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,710 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,523 questions
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 83,206 Reputation points
    2023-01-21T17:41:49.51+00:00

    It can be done from the PIDL

    This test with MS "Photos" works for me on Windows 10 :

                    string sAUMID = "Microsoft.Windows.Photos_8wekyb3d8bbwe!App";
                    Guid GUID_IShellItem = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE");
     
                    IntPtr psi = IntPtr.Zero;
                    HRESULT hr = SHGetKnownFolderItem(FOLDERID_AppsFolder, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, IntPtr.Zero, ref GUID_IShellItem, ref psi);
                    IntPtr psi2 = IntPtr.Zero;
                    hr = SHCreateItemFromRelativeName(psi, sAUMID, IntPtr.Zero, ref GUID_IShellItem, ref psi2);
                    if (hr == HRESULT.S_OK)
                    {
                        IntPtr pidlParent = IntPtr.Zero, pidlFull = IntPtr.Zero, pidlItem = IntPtr.Zero;
                        var aPidl = new IntPtr[255];
                        hr = SHGetIDListFromObject(psi2, out pidlFull);
                        if (hr == HRESULT.S_OK)
                        {    
                            pidlItem = ILFindLastID(pidlFull);
                            aPidl[0] = ILClone(pidlItem);
                            ILRemoveLastID(pidlFull);
                            pidlParent = ILClone(pidlFull);
                            ILFree(pidlFull);
    
                            System.Runtime.InteropServices.ComTypes.IDataObject pDataObject;
                            hr = SHCreateFileDataObject(pidlParent, 1, aPidl, null, out pDataObject);
                            if (hr == HRESULT.S_OK)
                            {
                                IntPtr pPath = IntPtr.Zero;
                                hr = SHGetKnownFolderPath(FOLDERID_Desktop, 0, IntPtr.Zero, out pPath);
                                string sPath = Marshal.PtrToStringUni(pPath);
                                //hr = SHCreateLinks(IntPtr.Zero, null, pDataObject, 1, IntPtr.Zero);
                                hr = SHCreateLinks(IntPtr.Zero, sPath, pDataObject, 1, IntPtr.Zero);
                                Marshal.ReleaseComObject(pDataObject);
                            }
                        }
                        Marshal.Release(psi2);
                    }
                    Marshal.Release(psi);
    

    with :

            public enum HRESULT : uint
            {
                S_OK = 0,
                S_FALSE = 1,
                E_NOINTERFACE = 0x80004002,
                E_NOTIMPL = 0x80004001,
                E_FAIL = 0x80004005,
                E_INVALIDARG = 0x80070057,           
                E_UNEXPECTED = 0x8000FFFF
            }
            
            [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern HRESULT SHGetKnownFolderItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid rfid, KNOWN_FOLDER_FLAG flags, IntPtr hToken, ref Guid riid, ref IntPtr ppv);
    
            [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern HRESULT SHGetKnownFolderPath([In, MarshalAs(UnmanagedType.LPStruct)] Guid rfid, int dwFlags, IntPtr hToken, out IntPtr ppszPath);
    
            public enum KNOWN_FOLDER_FLAG : uint
            {
                KF_FLAG_DEFAULT = 0x00000000,
                KF_FLAG_FORCE_APP_DATA_REDIRECTION = 0x00080000,
                KF_FLAG_RETURN_FILTER_REDIRECTION_TARGET = 0x00040000,
                KF_FLAG_FORCE_PACKAGE_REDIRECTION = 0x00020000,
                KF_FLAG_NO_PACKAGE_REDIRECTION = 0x00010000,
                KF_FLAG_FORCE_APPCONTAINER_REDIRECTION = 0x00020000,
                KF_FLAG_NO_APPCONTAINER_REDIRECTION = 0x00010000,
                KF_FLAG_CREATE = 0x00008000,
                KF_FLAG_DONT_VERIFY = 0x00004000,
                KF_FLAG_DONT_UNEXPAND = 0x00002000,
                KF_FLAG_NO_ALIAS = 0x00001000,
                KF_FLAG_INIT = 0x00000800,
                KF_FLAG_DEFAULT_PATH = 0x00000400,
                KF_FLAG_NOT_PARENT_RELATIVE = 0x00000200,
                KF_FLAG_SIMPLE_IDLIST = 0x00000100,
                KF_FLAG_ALIAS_ONLY = 0x80000000,
            }
    
            public static readonly Guid FOLDERID_Documents = new Guid(0xFDD39AD0, 0x238F, 0x46AF, 0xAD, 0xB4, 0x6C, 0x85, 0x48, 0x03, 0x69, 0xC7);       
            public static readonly Guid FOLDERID_AppsFolder = new Guid(0x1e87508d, 0x89c2, 0x42f0, 0x8a, 0x7e, 0x64, 0x5a, 0x0f, 0x50, 0xca, 0x58);
            public static readonly Guid FOLDERID_Desktop = new Guid(0xB4BFCC3A, 0xDB2C, 0x424C, 0xB0, 0x29, 0x7F, 0xE9, 0x9A, 0x87, 0xC6, 0x41);
    
            [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern HRESULT SHCreateItemFromRelativeName(IntPtr psiParent, string pszName, IntPtr pbc, ref Guid riid, ref IntPtr ppv);
    
            [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern HRESULT SHGetIDListFromObject(IntPtr punk, out IntPtr ppidl);
    
            [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            public static extern IntPtr ILFindLastID(IntPtr pidl);
    
            [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            public static extern IntPtr ILClone(IntPtr pidl);
    
            [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            public static extern Boolean ILRemoveLastID(IntPtr pidl);
    
            [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            public static extern void ILFree(IntPtr pidl);
    
            [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "#740")]
            public static extern HRESULT SHCreateFileDataObject(IntPtr pidlFolder, uint cidl, IntPtr[] apidl, System.Runtime.InteropServices.ComTypes.IDataObject pdtInner, out System.Runtime.InteropServices.ComTypes.IDataObject ppdtobj);
    
            [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "#172")]
            public static extern HRESULT SHCreateLinks(IntPtr hwnd, string pszDir, System.Runtime.InteropServices.ComTypes.IDataObject pDataObj, uint fFlags, IntPtr ppidl);
    
    

0 additional answers

Sort by: Most helpful