在 Windows 環境下開發時,經常需要遍歷指定資料夾,找出其中所有的快捷方式(.lnk 文件),並解析出它們指向的真實目標路徑。這對於構建啟動器、文件管理工具或自動化腳本非常有用。
主要分為兩步:
FindFirstFile/FindNextFile 或 std::filesystem (C++17) 遞歸掃描目標資料夾,篩選出擴展名為 .lnk 的文件。IShellLink 和 IPersistFile 接口,加載 .lnk 文件並調用 GetPath 方法獲取目標路徑。#include <windows.h>
#include <shlobj.h>
#include <iostream>
#include <string>
#include <vector>
#include <filesystem> // C++17
#pragma comment(lib, "shell32.lib")
std::vector<std::wstring> GetShortcutTargets(const std::wstring& folderPath) {
std::vector<std::wstring> targets;
// 1. 遍歷文件
for (const auto& entry : std::filesystem::recursive_directory_iterator(folderPath)) {
if (entry.path().extension() == L".lnk") {
// 2. 解析快捷方式
IShellLink* pShellLink = nullptr;
HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pShellLink);
if (SUCCEEDED(hr)) {
IPersistFile* pPersistFile = nullptr;
hr = pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);
if (SUCCEEDED(hr)) {
hr = pPersistFile->Load(entry.path().c_str(), STGM_READ);
if (SUCCEEDED(hr)) {
wchar_t targetPath[MAX_PATH];
hr = pShellLink->GetPath(targetPath, MAX_PATH, nullptr, SLGP_UNCPRIORITY);
if (SUCCEEDED(hr)) {
targets.push_back(targetPath);
}
}
pPersistFile->Release();
}
pShellLink->Release();
}
}
}
return targets;
}
CoInitialize(nullptr),結束時調用 CoUninitialize()。MAX_PATH,建議使用 GetPath 的擴展版本或動態分配緩衝區。