获取快捷方式的目标(.lnk)

问题描述 投票:0回答:1

[编辑-这个问题的标题具有误导性,所以我对其进行了编辑,无论如何,这个问题都是假的。 TL;DR - 零字节文件是我错误创建的]。请随意取消这个问题或将其留在这里作为我愚蠢的纪念碑。

我想获取快捷方式(.lnk)文件的目标。如果目标不存在,我想要一个空字符串(或返回 S_FALSE,无论哪种方式)。

此代码有效,除非目标不存在时,它会在目标应在的位置创建一个空文件。

有谁知道如何做到这一点?如果我删除对

persistFile->Load()
的调用,则无论目标是否存在,
shellLink->GetPath()
函数都会返回一个空字符串。

    HRESULT path_from_shortcut(std::wstring const &shortcut_filename, std::wstring &path)
    {
        HRESULT hr;
        
        ComPtr<IShellLinkW> shellLink;
        hr = CoCreateInstance(CLSID_ShellLink,
                                NULL,
                                CLSCTX_INPROC_SERVER,
                                IID_IShellLinkW,
                                reinterpret_cast<LPVOID *>(shellLink.GetAddressOf()));

        if(FAILED(hr)) {
            return hr;
        }

        ComPtr<IPersistFile> persistFile;
        hr = shellLink->QueryInterface(IID_IPersistFile, reinterpret_cast<LPVOID *>(persistFile.GetAddressOf()));

        if(FAILED(hr)) {
            return hr;
        }

        // don't look for it if it's not there

        hr = shellLink->Resolve(null, SLR_NO_UI | SLR_NOUPDATE | SLR_NOSEARCH | SLR_NOTRACK | 0x00010000);

        if(FAILED(hr)) {
            return S_FALSE;
        }

        // persistFile->Load() creates a zero byte file at the target location if it doesn't exist

        hr = persistFile->Load(shortcut_filename.c_str(), STGM_READ);

        if(FAILED(hr)) {
            return S_FALSE;
        }

        wchar_t target_path[MAX_PATH * 4];
        hr = shellLink->GetPath(target_path, _countof(target_path), 0, SLGP_RAWPATH);

        if(FAILED(hr)) {
            return S_FALSE;
        }

        path = std::wstring(target_path);
        return S_OK;
    }
c++ winapi
1个回答
0
投票

如果有人遇到这个问题寻找已编辑问题的答案,这就是我的结局:

    HRESULT path_from_shortcut(std::wstring const &shortcut_filename, std::wstring &path)
    {
        ComPtr<IShellLinkW> shellLink;
        HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shell_link));

        if(FAILED(hr)) {
            return hr;
        }

        ComPtr<IPersistFile> persistFile;
        hr = shellLink.As(&persistFile);

        if(FAILED(hr)) {
            return hr;
        }

        hr = persistFile->Load(shortcut_filename.c_str(), STGM_READ);

        if(FAILED(hr)) {
            return hr;
        }

        LPITEMIDLIST itemIdList{NULL};
        hr = shellLink->GetIDList(&itemIdList);

        if(FAILED(hr)) {
            return hr;
        }

        wchar target_path[MAX_PATH];

        hr = E_FAIL;

        if(SHGetPathFromIDList(itemIdList, target_path)) {
            path = std::wstring(target_path);
            hr = S_OK;
        }

        if(itemIdList != NULL) {
            CoTaskMemFree(itemIdList);
        }
        return hr;
    }
© www.soinside.com 2019 - 2024. All rights reserved.