【问题标题】:IShellLink - how to get the original target pathIShellLink - 如何获取原始目标路径
【发布时间】:2021-08-21 17:44:44
【问题描述】:

我在 Windows PC 中创建了一个shortcut,目标路径为:

C:\Users\b\Desktop\New Text Document.txt

然后我将快捷方式复制到另一台具有不同用户名的PC上,我想检索原始目标路径。

如果你用文本编辑器打开快捷方式文件,可以看到原来的路径被保留了,所以目标肯定是可以的。

尽管存在SLGP_RAWPATH,但以下代码不起作用。它输出:

C:\Users\a\Desktop\New Text Document.txt

它正在将用户文件夹名称更改为与正在运行的程序关联的名称。

我知道问题不在于环境变量,因为在文件中看不到环境变量名称。但我找不到任何关于这种自动重定位行为的文档。

IShellLinkW*lnk;
if (CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&lnk) == 0){
    IPersistFile* file;
    if (lnk->QueryInterface(IID_IPersistFile, (void**)&file) == 0){
        if (file->Load(L"shortcut", 0) == 0){
            wchar_t path[MAX_PATH];
            if (lnk->GetPath(path, _countof(path), 0, SLGP_RAWPATH) == 0){
                _putws(path);
            }
            IShellLinkDataList* sdl;
            if (lnk->QueryInterface(IID_IShellLinkDataList, (void**)&sdl) == 0){
                EXP_SZ_LINK* lnkData;
                if (sdl->CopyDataBlock(EXP_SZ_LINK_SIG, (void**)&lnkData) == 0){
                    _putws(lnkData->swzTarget);
                    LocalFree(lnkData);
                }
                sdl->Release();
            }
        }
        file->Release();
    }
    lnk->Release();
}

【问题讨论】:

    标签: windows winapi com


    【解决方案1】:

    您的快捷方式是一个.lnk 文件,只是没有.lnk 文件扩展名。根据微软最新的"Shell Link (.LNK) Binary File Format" documentation,您的快捷方式似乎被配置为relative 文件目标。相对名称只是New Text Document.txt。我没有深入研究该文件,但我猜测它与系统的桌面文件夹相关,因此无论当前 PC 的实际桌面文件夹是什么,它都会占用。这可以解释为什么在更改 PC 时查询目标会将相对根从 C:\Users\b\Desktop 更改为 C:\Users\a\Desktop

    至于能不能查询到原来的目标C:\Users\b\Desktop\New Text Document.txt,这个我就不知道了。它也存在于文件中,因此在 theory 中应该有一种方法可以查询它,但我不知道它在哪个字段中,而无需花时间完全解码此文件。您应该尝试使用上述文档编写自己的解码器。

    【讨论】:

      【解决方案2】:

      Windows Shell Link 类实现了property store,因此您可以使用如下代码访问它(使用 ATL 智能指针):

      int main()
      {
          // note: error checking omitted!
          CoInitialize(NULL);
          {
              CComPtr<IShellLink> link;
              link.CoCreateInstance(CLSID_ShellLink);
      
              CComPtr<IPersistFile> file;
              link->QueryInterface(&file);
      
              file->Load(L"shortcut", STGM_READ);
      
              // get the property store
              CComPtr<IPropertyStore> ps;
              link->QueryInterface(&ps);
      
              // dump all properties
              DWORD count = 0;
              ps->GetCount(&count);
              for (DWORD i = 0; i < count; i++)
              {
                  PROPERTYKEY pk;
                  ps->GetAt(i, &pk);
      
                  // get property's canonical name from pk
                  CComHeapPtr<wchar_t> name;
                  PSGetNameFromPropertyKey(pk, &name);
      
                  PROPVARIANT pv;
                  PropVariantInit(&pv);
                  ps->GetValue(pk, &pv);
      
                  // convert PropVariants to a string to be able to display
                  CComHeapPtr<wchar_t> valueAsString;
                  PropVariantToStringAlloc(pv, &valueAsString); // propvarutil.h
      
                  wprintf(L"%s: %s\n", name, valueAsString);
                  PropVariantClear(&pv);
              }
          }
          CoUninitialize();
          return 0;
      }
      

      它会输出这个:

      System.ItemNameDisplay: New Text Document.txt
      System.DateCreated: 2021/06/03:14:45:30.000
      System.Size: 0
      System.ItemTypeText: Text Document
      System.DateModified: 2021/06/03:14:45:29.777
      System.ParsingPath: C:\Users\b\Desktop\New Text Document.txt
      System.VolumeId: {E506CEB2-0000-0000-0000-300300000000}
      System.ItemFolderPathDisplay: C:\Users\b\Desktop
      

      所以,你正在寻找System.ParsingPath,你可以像这样直接得到它:

      ...   
      ps->GetValue(PKEY_ParsingPath, &pv); // propkey.h
      ...   
      

      【讨论】:

        猜你喜欢
        • 2010-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-17
        • 1970-01-01
        • 1970-01-01
        • 2010-11-02
        • 2016-06-02
        相关资源
        最近更新 更多