You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Shell扩展的IShellExtInit::Initialize中获取触发菜单的文件路径

正确获取Shell扩展右键菜单触发文件路径的方法

你之前的问题出在错误使用了pidlFolder参数——这个参数是文件所在文件夹的PIDL,并非你右键点击的目标文件本身。要获取触发菜单的文件路径,必须通过IDataObject参数提取CF_HDROP格式的数据,这是Shell传递选中文件信息的标准方式。

以下是修正后的IShellExtInit::Initialize实现代码:

// IShellExtInit
HRESULT Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgID)
{
    std::wstring result;

    // 先检查IDataObject是否有效
    if (!pdtobj)
    {
        result += L"IDataObject is null";
        MessageBox(NULL, result.c_str(), L"Error", MB_OK);
        return E_INVALIDARG;
    }

    // 准备FORMATETC结构,指定CF_HDROP格式
    FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
    STGMEDIUM stm;
    ZeroMemory(&stm, sizeof(stm));

    // 从IDataObject中获取HDROP数据
    HRESULT hr = pdtobj->GetData(&fe, &stm);
    if (FAILED(hr))
    {
        result += L"Failed to get HDROP data, HRESULT: " + std::to_wstring(hr);
        MessageBox(NULL, result.c_str(), L"Error", MB_OK);
        return hr;
    }

    HDROP hDrop = static_cast<HDROP>(stm.hGlobal);
    if (!hDrop)
    {
        result += L"HDROP handle is null";
        MessageBox(NULL, result.c_str(), L"Error", MB_OK);
        ReleaseStgMedium(&stm);
        return E_FAIL;
    }

    // 获取选中文件的数量
    UINT fileCount = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
    if (fileCount == 0)
    {
        result += L"No files selected";
        MessageBox(NULL, result.c_str(), L"Info", MB_OK);
        ReleaseStgMedium(&stm);
        return S_OK;
    }

    // 提取第一个文件的路径(如果是多选,可循环处理所有文件)
    TCHAR path[MAX_PATH];
    if (DragQueryFile(hDrop, 0, path, MAX_PATH))
    {
        result += L"Selected file path: " + std::wstring(path);
    }
    else
    {
        result += L"Failed to get file path";
    }

    MessageBox(NULL, result.c_str(), L"Result", MB_OK);

    // 释放STGMEDIUM资源
    ReleaseStgMedium(&stm);

    return S_OK;
}

关键要点说明:

  • CF_HDROP是Shell用于传递拖拽/选中文件列表的标准剪贴板格式,右键菜单触发时,Shell会把选中的文件信息打包到这个格式里。
  • 使用DragQueryFile可以从HDROP句柄中提取单个或多个文件的路径:第一个参数传0xFFFFFFFF可获取选中文件总数,传索引值(从0开始)可获取对应文件的路径。
  • 必须调用ReleaseStgMedium释放GetData获取的STGMEDIUM资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Joe J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:03:17