首先,需要使用 node-gyp 来编译 C++ 模块。在模块中,需要使用 Windows API 中的一些函数来获取当前鼠标所在的窗口句柄及其所在的文件夹路径。

以下是实现方式:

  1. 导入头文件
#include <Windows.h>
#include <ShlObj.h>
#include <ShObjIdl.h>
  1. 获取当前鼠标所在的窗口句柄
HWND hWnd = GetForegroundWindow();
  1. 枚举所有资源管理器窗口,获取当前窗口所在的文件夹路径
IShellWindows *psw;
HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw));
if (SUCCEEDED(hr)) {
    VARIANT vEmpty = {};
    VARIANT v;
    IUnknown *punk;
    IDispatch *pdisp;
    IWebBrowserApp *pwba;
    IShellBrowser *psb;
    LPITEMIDLIST pidl;
    TCHAR szPath[MAX_PATH];
    LONG lhwnd;
    BSTR bstrName;
    hr = psw->lpVtbl->get_Count(psw, &lhwnd);
    for (int i = 0; i < lhwnd; i++) {
        v.vt = VT_I4;
        v.lVal = i;
        hr = psw->lpVtbl->Item(psw, v, &punk);
        if (SUCCEEDED(hr)) {
            hr = punk->lpVtbl->QueryInterface(punk, IID_PPV_ARGS(&pdisp));
            if (SUCCEEDED(hr)) {
                hr = pdisp->lpVtbl->QueryInterface(pdisp, IID_PPV_ARGS(&pwba));
                if (SUCCEEDED(hr)) {
                    hr = pwba->lpVtbl->get_HWND(pwba, &hWnd);
                    if (SUCCEEDED(hr) && hWnd == hwnd) {
                        hr = pdisp->lpVtbl->QueryInterface(pdisp, IID_PPV_ARGS(&psb));
                        if (SUCCEEDED(hr)) {
                            hr = psb->lpVtbl->QueryActiveShellView(psb, &punk);
                            if (SUCCEEDED(hr)) {
                                hr = punk->lpVtbl->QueryInterface(punk, IID_PPV_ARGS(&psv));
                                if (SUCCEEDED(hr)) {
                                    hr = psv->lpVtbl->GetItemObject(psv, SVGIO_BACKGROUND, IID_PPV_ARGS(&punk));
                                    if (SUCCEEDED(hr)) {
                                        hr = punk->lpVtbl->QueryInterface(punk, IID_PPV_ARGS(&psf));
                                        if (SUCCEEDED(hr)) {
                                            hr = psf->lpVtbl->ParseDisplayName(psf, hwnd, NULL, bstrName, NULL, &pidl, NULL);
                                            if (SUCCEEDED(hr)) {
                                                hr = SHGetPathFromIDList(pidl, szPath);
                                                if (SUCCEEDED(hr)) {
                                                    // 输出文件夹路径
                                                    return szPath;
                                                }
                                                ILFree(pidl);
                                            }
                                            psf->lpVtbl->Release(psf);
                                        }
                                        punk->lpVtbl->Release(punk);
                                    }
                                    psv->lpVtbl->Release(psv);
                                }
                            }
                            psb->lpVtbl->Release(psb);
                        }
                    }
                    pwba->lpVtbl->Release(pwba);
                }
                pdisp->lpVtbl->Release(pdisp);
            }
            punk->lpVtbl->Release(punk);
        }
    }
    psw->lpVtbl->Release(psw);
}

最终,将上面的代码封装成一个 C++ 函数,再使用 N-API 将其暴露给 JavaScript 即可。

Node.js C++ 模块实现获取资源管理器当前路径

原文地址: https://www.cveoy.top/t/topic/oFue 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录