为什么在c++中用shell链接查找快捷方式的目标路径时,它指的是windowsinstaller文件夹

Why in finding target path of shortcut with shell link in c++ it refers to windowsinstaller folder

本文关键字:文件夹 windowsinstaller 目标路径 为什么 中用 c++ shell 链接 快捷方式 查找      更新时间:2023-10-16



我想在startmenu文件夹中查找快捷方式的目标路径,

我知道应该使用来自shell的链接组件对象模型,
但在我对一些快捷方式的测试中,它显示:

"windows\installer\{guid}\x.exe ">

并且不显示它的程序文件文件夹,对于其他快捷方式,它运行良好,

我如何才能找到这些产品的目标路径
这是我使用的功能:

    HRESULT TargetShortcut::ResolveIt(HWND hwnd, LPCTSTR lpszLinkFile, LPTSTR lpszPath, int iPathBufferSize)
    {
        HRESULT hres;
        if (lpszPath == NULL)
            return E_INVALIDARG;
        *lpszPath = 0;
        // Get a pointer to the IShellLink interface. It is assumed that CoInitialize
        // has already been called.
        IShellLink* __psl = NULL;
        HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
        if (SUCCEEDED(hres))
        {
            // Get a pointer to the IPersistFile interface.
            IPersistFile* ppf = NULL;
            hres = __psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
            if (SUCCEEDED(hres))
            {
                // Add code here to check return value from MultiByteWideChar
                // for success.
                // Load the shortcut.
    #ifdef _UNICODE
                hres = ppf->Load(lpszLinkFile, STGM_READ);
    #else
                WCHAR wsz[MAX_PATH] = {0};
                // Ensure that the string is Unicode.
                MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz, MAX_PATH);
                hres = ppf->Load(wsz, STGM_READ);
    #endif
                if (SUCCEEDED(hres))
                {
                    // Resolve the link.
                    hres = __psl->Resolve(hwnd, 0);
                    if (SUCCEEDED(hres))
                    {
                        // Get the path to the link target.
                        TCHAR szGotPath[MAX_PATH] = {0};
                        hres = __psl->GetPath(szGotPath, _countof(szGotPath), NULL, SLGP_SHORTPATH);
                        if (SUCCEEDED(hres))
                        {
                            hres = StringCbCopy(lpszPath, iPathBufferSize, szGotPath);
                        }
                    }
                }
                // Release the pointer to the IPersistFile interface.
                ppf->Release();
            }
            // Release the pointer to the IShellLink interface.
            __psl->Release();
        }
        return hres;
    }

这是一个快捷方式的答案:

 C:WindowsInstaller{53FA9A9F-3C19-4D43-AD6B-DEF365D469BA}

首先尝试此代码:

#include "msi.h"
#pragma comment (lib, "msi")
...
TCHAR Path[MAX_PATH];
Path[0] = '';            
TCHAR pszComponentCode[MAX_FEATURE_CHARS+1];
TCHAR pszProductCode[MAX_FEATURE_CHARS+1];
pszComponentCode[0] = _T('');
pszProductCode[0] = _T('');
if ( MsiGetShortcutTarget(pszLinkPathName, pszProductCode, NULL, pszComponentCode) == ERROR_SUCCESS)
{
    DWORD dw = MAX_PATH;
    UINT ret = MsiGetComponentPath(pszProductCode, pszComponentCode, Path, &dw);
    //Path now contains path to EXE
}
else
{
   //process regular LNK
}

然后在ELSE部分,您可以调用代码来解析常规LNK