Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

std::filesystem i pliki lnk - czyli jak wyciągnąć ścieżki do plików ze skrótów

Ostatnio zmodyfikowano 2025-09-29 05:40
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
std::filesystem i pliki lnk - czyli jak wyciągnąć ścieżki do plików ze skrótów
» 2025-09-28 07:44:25
Witam. Potrzebuję wyciągnąć z plików skrótów lnk ścieżki plików na które wskazują. Jak to zrobić ?

C/C++
std::filesystem::path getPathFromlnk( std::filesystem::directory_entry entry ) {
   
return std::filesystem::absolute( entry ); // wiem, że błędne ale przynajmniej wiadomo o co chodzi
}

//////////////////////////////////////////////////////////////////////////////
LocationRect::LocationRect( std::wstring path )
    :
ElementGUI()
{
   
_rect = sf::RectangleShape();
   
_rect.setFillColor( sf::Color( 95, 47, 47 ) );
   
_rect.setOutlineThickness( 1.0f );
   
_rect.setOutlineColor( sf::Color( 63, 47, 47 ) );
   
   
std::filesystem::directory_entry entry( path );
   
//_path = entry.path();
   
_path = getPathFromlnk( entry );
   
   
_ico = sf::Sprite();
   
if( entry.is_block_file() )
       
 _ico.setTexture( * getTexture( L"tex\\dialog\\harddrive.png" )->_texture );
   
else if( entry.is_directory() )
       
 _ico.setTexture( * getTexture( L"tex\\dialog\\dictionary.png" )->_texture );
   
else
       
 _ico.setTexture( * getTexture( L"tex\\dialog\\empty.png" )->_texture );
   
   
_text = sf::Text();
   
_text.setFont( basicFont );
   
_text.setCharacterSize( dialog_content_font_size );
   
_text.setFillColor( normal_text_color );
   
_text.setString( _path.filename().wstring() );
}

Jeżeli potrzebujesz zbudować program do testów to zamieszczam poniżej link do repozytorium
https://github.com/tBane1995/Anim-Paint.git
Lokalizacja kodu:
Anim-Paint\Source Files\Dialogs\Dialog_Save_As.cpp
P-183055
pekfos
» 2025-09-29 00:52:35
P-183059
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-29 05:32:58
Działa :-)

C/C++
#include <shobjidl.h>    // IShellLink
#include <objbase.h>     // CoInitializeEx

// ...
// ...
// ...

//////////////////////////////////////////////////////////////////////////////

inline bool is_lnk( const std::filesystem::path & p ) {
   
std::wstring ext = p.extension().wstring(); // zawiera kropkę, np. L".lnk"
   
std::transform( ext.begin(), ext.end(), ext.begin(),::towlower );
   
return ext == L".lnk";
}

inline std::filesystem::path resolve_lnk( const std::filesystem::path & lnkPath ) {
   
std::filesystem::path result;
   
   
// COINIT_APARTMENTTHREADED jest OK do prostych wywołań Shell
   
HRESULT hrCo = CoInitializeEx( nullptr, COINIT_APARTMENTTHREADED );
   
bool comInit = SUCCEEDED( hrCo );
   
   
IShellLinkW * psl = nullptr;
   
if( SUCCEEDED( CoCreateInstance( CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
   
IID_PPV_ARGS( & psl ) ) ) ) {
       
IPersistFile * ppf = nullptr;
       
if( SUCCEEDED( psl->QueryInterface( IID_PPV_ARGS( & ppf ) ) ) ) {
           
if( SUCCEEDED( ppf->Load( lnkPath.c_str(), STGM_READ ) ) ) {
               
WCHAR szTarget[ MAX_PATH ] = { };
               
WIN32_FIND_DATAW wfd { };
               
// SLGP_UNCPRIORITY -> preferuj ścieżkę UNC, ale SLGP_RAWPATH też jest ok
               
if( SUCCEEDED( psl->GetPath( szTarget, MAX_PATH, & wfd, SLGP_UNCPRIORITY ) ) ) {
                   
result = szTarget;
               
}
            }
           
ppf->Release();
       
}
       
psl->Release();
   
}
   
   
if( comInit ) CoUninitialize();
   
   
return result; // może być pusty, jeśli nie udało się rozwiązać
}

std::filesystem::path getPath( std::filesystem::directory_entry entry ) {
   
if( is_lnk( entry.path() ) ) {
       
// shortcut file
       
std::filesystem::path path = resolve_lnk( entry.path() );
       
std::wcout << L"is lnk: " << path.wstring() << std::endl;
       
return path;
   
}
   
else {
       
// other file
       
std::wcout << L"is other: " << entry.path().wstring() << std::endl;
       
return entry.path();
   
}
}

//////////////////////////////////////////////////////////////////////////////
P-183060
« 1 »
  Strona 1 z 1