【问题标题】:Why in finding target path of shortcut with shell link in c++ it refers to windows\installer folder为什么在 C++ 中使用 shell 链接查找快捷方式的目标路径时,它指的是 windows\installer 文件夹
【发布时间】:2026-01-16 22:55:01
【问题描述】:



我想在开始菜单文件夹中找到快捷方式的目标路径,

我知道应该从 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:\Windows\Installer{53FA9A9F-3C19-4D43-AD6B-DEF365D469BA} 

【问题讨论】:

  • 这是 Camtasia 安装程序的路径还是 UUID 的匹配只是巧合?
  • 并非所有快捷方式都引用磁盘上的文件。例如,您可以拥有网站的快捷方式或控制面板项目的快捷方式。这些快捷方式没有SFGAO_FILESYSTEM 属性。如果您询问路径,即使它不是磁盘上的文件,它们也会构成一个人为路径。这就是你在这里得到的。这是动态安装程序的人工路径。
  • @HelloWorld :这只是巧合
  • @Raymond Chen:但是当我双击开始菜单文件夹中的快捷方式时,程序运行。 windows如何从这些人工路径中理解真实路径?
  • 当您双击快捷方式时,快捷方式的处理程序会开始工作并确定您正在运行的程序,并在必要时安装/更新程序,然后运行它。 (请注意,如果程序是按需安装的,它还没有真正的路径。)如果您想自己做所有这些,您可以询问 MSI。

标签: c++ windows shortcut


【解决方案1】:

先试试这个代码:

#include "msi.h"

#pragma comment (lib, "msi")

...
TCHAR Path[MAX_PATH];
Path[0] = '\0';            
TCHAR pszComponentCode[MAX_FEATURE_CHARS+1];
TCHAR pszProductCode[MAX_FEATURE_CHARS+1];
pszComponentCode[0] = _T('\0');
pszProductCode[0] = _T('\0');

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

【讨论】:

  • 您可能希望向询问他们应该修改/更新的代码的重要部分的人突出显示
最近更新 更多