为什么在使用c++中的shell link查找快捷方式目标路径时会涉及到windows\installer文件夹?

3
我希望能够找到开始菜单文件夹中快捷方式的目标路径,

我知道应该使用shell link组件对象模型,
但在我的测试中,对于某些快捷方式,它显示:

"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的匹配只是巧合? - HelloWorld
1
并非所有的快捷方式都指向磁盘上的文件。例如,您可以有指向网站或控制面板项目的快捷方式。这些快捷方式没有 SFGAO_FILESYSTEM 属性。即使它不是磁盘上的文件,如果您请求路径,它们也会编造一个人工路径。这就是您在此处获得的内容。它是动态安装程序的人工路径。 - Raymond Chen
@HelloWorld:这只是一种巧合。 - nazanin
@Raymond Chen:但是当我双击开始菜单文件夹中的快捷方式时,程序会运行。Windows如何理解这些人工路径的真实路径? - nazanin
1
当您双击快捷方式时,快捷方式的处理程序开始工作,并确定您正在运行哪个程序。 如果需要安装/更新程序,则会进行安装/更新,然后启动该程序。(请注意,如果程序是按需安装的,则尚无真实路径。)如果您想亲自完成所有这些工作,可以向MSI提出要求。 - Raymond Chen
1个回答

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。

你可能需要强调给询问者代码中他们应该修改/更新的重要部分。 - Paul Bastide

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接