locked
how to use API to pin a shortcut to start in windows 8.1 by C/C++? RRS feed

  • Question

  • I've put the shortcut.lnk into c:\ProgramData\Microsoft\Windows\Start Menu\Programs\

    in Win8 or below, it seems work fine:

    In win8, OS creates the shortcut in the start screen automatically;

    In older OS,  it creates the shortcut in the start menu.

    However, in win 8.1, it does not appear in the start screen!

    User need to right click on the shortcut tile, and then select "pin to start" manually.

    My question is: how to do it by API?

    I've tried the solution as follow:

    //

    BOOL PinToStart( LPCWSTR szFilePath )
    {
        BOOL bSuccess = FALSE;

        // break into file name and path
        WCHAR lpszDirectoryName[ MAX_PATH ] = { 0 };
        LPCWSTR lpszFileName = ::PathFindFileName( szFilePath );

        wcscpy_s( lpszDirectoryName, szFilePath );
        ::PathRemoveFileSpec( lpszDirectoryName );

        // load shell32.dll
        HMODULE hShell32 = LoadLibrary( L"SHELL32" );
        if( hShell32 != NULL )
        {
            // get the localized translation of 'Pin to Start' verb
            WCHAR szPinToStartLocalized[ MAX_PATH ] = { 0 };
            int nPinToStartLocalizedLength = LoadString( (HINSTANCE)hShell32, 51201, szPinToStartLocalized, MAX_PATH );

            if(  nPinToStartLocalizedLength > 0 )
            {
                // create the shell object
                IShellDispatch *pShellDispatch = NULL;
                HRESULT hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void**)&pShellDispatch);
                if( SUCCEEDED( hr ) )
                {
                    Folder *pFolder = NULL;
                    variant_t vaDirectory( lpszDirectoryName );

                    // get the namespace
                    if( SUCCEEDED( pShellDispatch->NameSpace( vaDirectory, &pFolder ) ) )
                    {
                        FolderItem *pItem = NULL;
                        bstr_t vaFileName( lpszFileName );

                        // parse the name
                        if( SUCCEEDED( pFolder->ParseName( vaFileName, &pItem ) ) )
                        {
                            FolderItemVerbs* pVerbs = NULL;

                            // get the verbs
                            if( SUCCEEDED( pItem->Verbs(&pVerbs) ) )
                            {
                                long nCount = 0;

                                if( SUCCEEDED ( pVerbs->get_Count( &nCount ) ) )
                                {
                                    variant_t vaIndex;
                                    vaIndex.vt = VT_I4;

                                    // iterate through verbs
                                    for( vaIndex.lVal = 0; vaIndex.lVal<nCount; vaIndex.lVal++ )
                                    {
                                        FolderItemVerb* pVerb = NULL;

                                        if( SUCCEEDED( pVerbs->Item( vaIndex, &pVerb ) ) )
                                        {
                                            BSTR bstrVerbName = NULL;

                                            // check for 'Pin to Start' verb
                                            if( SUCCEEDED( pVerb->get_Name( &bstrVerbName ) ) )
                                            {
                                                if( 0 == wcscmp( bstrVerbName, szPinToStartLocalized ) )
                                                {
                                                    bSuccess = SUCCEEDED( pVerb->DoIt() );
                                                    vaIndex.lVal = nCount; // break for
                                                }

                                                ::SysFreeString( bstrVerbName );
                                            }
                                            pVerb->Release();
                                        } // if
                                    } // for
                                }
                                pVerbs->Release();
                            }
                            pItem->Release();
                        }
                        pFolder->Release();
                    }
                    pShellDispatch->Release();
                }
            }

            ::FreeLibrary( hShell32 );
        }

        return bSuccess;
    }

    //

    However, the list of verbs do not contain "pin to start"; the nearest thing I've got is "pin to taskbar", which is not what I want.

    Monday, July 22, 2013 10:24 AM

Answers

  • I compared Win8 & 8.1. It seems there were changes. The Start only has now links that are places using "Pin to Start", it is now more comparable to the option "Pin to Startmenu" in Windows 7.

    Officially there is not API to pin a application to Start or the Taskbar. This is a user decision and not the decision of an application creater or an installer to pin an application.


    Best regards

    Bordon

    Note: Posted code pieces may not have a good programming style and may not perfect. It is also possible that they do not work in all situations. Code pieces are only indended to explain something particualar.

    Thursday, July 25, 2013 5:41 PM

All replies

  • In windows 8.1 you do not have a StartMenu (win8 also has no start menu), you will be redirected to the pane with the tiles. For this reason you can not pin to the StartMenu, tere is no StartMenu, only a start button.

    Therefore I'm surprised the Pin to StartMenu works in win8. Maybe the reason that it is not working in win8.1 since some stuff works not correctly in Win8.1. It is still a prefrlease. The Start window is reworked a lot in Win8.1 for this reason if may be possible that there is a bug or an open point.

    At the moement I do not have access to a win8.1 system. In a few hours I can check it on a win8.1 Preview Test System.


    Best regards

    Bordon

    Note: Posted code pieces may not have a good programming style and may not perfect. It is also possible that they do not work in all situations. Code pieces are only indended to explain something particualar.



    • Edited by Bordon Monday, July 22, 2013 10:45 AM ----
    • Proposed as answer by May Wang - MSFT Wednesday, July 24, 2013 3:32 AM
    Monday, July 22, 2013 10:38 AM
  • I compared Win8 & 8.1. It seems there were changes. The Start only has now links that are places using "Pin to Start", it is now more comparable to the option "Pin to Startmenu" in Windows 7.

    Officially there is not API to pin a application to Start or the Taskbar. This is a user decision and not the decision of an application creater or an installer to pin an application.


    Best regards

    Bordon

    Note: Posted code pieces may not have a good programming style and may not perfect. It is also possible that they do not work in all situations. Code pieces are only indended to explain something particualar.

    Thursday, July 25, 2013 5:41 PM