Разрешение ссылок оболочки Windows (ярлыки) в C ++ - PullRequest
0 голосов
/ 16 октября 2019

Каков наилучший способ разыменования ссылки на оболочку Windows (ярлык) в коде C ++?

Я использовал функцию DeReferenceShellLink (), написанную Бретом Пёрсоном для Windows Developer Journal, но этот код, вероятно,10-20 лет сейчас. Я хотел бы заменить его новейшими технологиями, так как этот код становится проблематичным для поддержки

        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       //   DerefLnk.cpp
       //     Bret S. Pehrson for Windows Developer's Journal
       // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       //DeReferenceShellLink
       //   Parameters:
       //     lpszLinkName - link name to dereference
       //     lpszDest - destination to store dereferenced name
       //     cchDest - size of destination buffer, in characters
       //   Return: 
       //     Number of characters ( including NULL ) for complete 
       //     dereferenced name
       //   Notes: 
       //     lpszLinkName and lpszDest can point to the same buffer.
       //     If NULL is specified for lpszDest, the dereferenced name
       //     is not copied to the destination, but the return value is
       //     still computed.
       //
       // Requires link library : ole32.dll
       //
       // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       UINT DeReferenceShellLink( 
          LPCTSTR lpszLinkName, 
          LPTSTR lpszDest, 
          UINT cchDest )
       {
          // STACK variables
          const LPCTSTR   lpszExt = _tcsrchr( lpszLinkName, '.' );
          WIN32_FIND_DATA fd;
          IPersistFile *   pPersistFile = NULL; 
          IShellLink *   pShellLink = NULL; 
          LPCOLESTR      lpOleStrLinkName;
          HRESULT       hResult;
          TCHAR         szPath[_MAX_PATH+1];
          UINT         cchDeref = 0;
          #ifndef UNICODE
          UINT         cbAlloc;
          #endif //!UNICODE

          // Initialization
          fd.cFileName[0] = NULL;
          szPath[0]      = NULL;
          // Dereference as necessary
          if ( ( lpszExt!=NULL ) && ( lstrcmpi( lpszExt, TEXT( ".lnk" ) )==0 ) )
          {
             // Initialize COM
             hResult = CoInitialize( NULL );
             if ( SUCCEEDED( hResult ) )
             {
                // Create an instance of shell link interface
                hResult = CoCreateInstance( 
                   CLSID_ShellLink, 
                   NULL, 
                   CLSCTX_INPROC_SERVER, 
                   IID_IShellLink, 
                   ( LPVOID * )&pShellLink );
                if ( SUCCEEDED( hResult ) )
                {
                   // Get the persist file interface
                   hResult = pShellLink->QueryInterface( 
                      IID_IPersistFile, 
                      ( LPVOID * )&pPersistFile );
                   if ( SUCCEEDED( hResult ) )
                   {
                      // Convert the link name to unicode as necessary
                      #ifdef UNICODE
                      lpOleStrLinkName = lpszLinkName;
                      #else //!UNICODE
                      int cchString = lstrlen( lpszLinkName ) + 1;
                      cbAlloc = cchString * sizeof( OLECHAR );
                      lpOleStrLinkName = ( LPOLESTR )_alloca( cbAlloc );
                      MultiByteToWideChar( 
                         CP_ACP, 
                         MB_PRECOMPOSED, 
                         lpszLinkName, 
                         cchString, 
                         ( LPOLESTR )lpOleStrLinkName, 
                         cchString );
                      #endif //!UNICODE
                      // Load the persist file with the link
                      hResult = pPersistFile->Load( 
                         lpOleStrLinkName, 
                         0 );
                      if ( SUCCEEDED( hResult ) )
                      {
                         // Resolve the link
                         hResult = pShellLink->Resolve( 
                            NULL, 
                            SLR_NO_UI );
                         if ( SUCCEEDED( hResult ) )
                         {
                            // Get the path from the link
                            hResult = pShellLink->GetPath( 
                               szPath, 
                               sizeof( szPath )/sizeof( szPath[0] ), 
                               &fd, 
                               0 );
                            if ( hResult == S_OK )
                            {
                               // Copy to destination
                               cchDeref = lstrlen( szPath ) + 1;
                               if ( lpszDest != NULL )
                               {
                                  lstrcpyn( 
                                     lpszDest,
                                     szPath,
                                     cchDest );
                               }
                            }
                         }
                      }
                      pPersistFile->Release();
                      //pPersistFile = NULL; CppCheck flags this as unused assignment
                   }
                   pShellLink->Release();
                   // pShellLink = NULL; CppCheck flags this as unused assignment
                }
                CoUninitialize();
             }
          }
          else
          {
             // Not a shell link, simply copy source to destination
             if ( ( lpszLinkName!=lpszDest ) && ( lpszDest!= NULL ) )
             {
                lstrcpyn( lpszDest, lpszLinkName, cchDest );
             }
             cchDeref = lstrlen( lpszLinkName ) + 1;
          }
          // Done
          return cchDeref;
       }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...