常用的就两种,第一种同时兼容 Win7。第二种只发现支持 Win10,11。
第一种:
#include <Windows.h>
#include <atlbase.h>
#include <atlcomcli.h>
#include <iostream>
#include <string>
#include <io.h>
#include <fcntl.h>
#include <locale.h>
#include <comutil.h>#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "comsuppw.lib")void InitializeConsole() {// 设置区域环境以支持中文字符输出setlocale(LC_ALL, "zh-CN");// 将控制台输出模式设置为支持 UTF-8int res = _setmode(_fileno(stdout), _O_U8TEXT);
}void PrintError(const wchar_t* context, HRESULT hr) {std::wcerr << L"Error in " << context << L": HRESULT " << hr << std::endl;
}int main() {InitializeConsole();std::wcout << L"Starting program..." << std::endl;HRESULT hr = CoInitialize(NULL);if (FAILED(hr)) {PrintError(L"CoInitialize", hr);return 1;}// 获取 CLSID for Shell.ApplicationCLSID clsidShellApp;hr = CLSIDFromProgID(L"Shell.Application", &clsidShellApp);if (FAILED(hr)) {PrintError(L"CLSIDFromProgID for Shell.Application", hr);CoUninitialize();return 1;}// 创建 Shell.Application COM 对象CComPtr<IDispatch> spShellApp;hr = CoCreateInstance(clsidShellApp, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&spShellApp));if (FAILED(hr)) {PrintError(L"CoCreateInstance for Shell.Application", hr);CoUninitialize();return 1;}// 获取 Windows 集合CComVariant result;DISPID dispid;OLECHAR* methodName = (OLECHAR*)L"Windows";hr = spShellApp->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_USER_DEFAULT, &dispid);if (FAILED(hr)) {PrintError(L"GetIDsOfNames for Windows", hr);// `spShellApp` 销毁spShellApp.Release();CoUninitialize();return 1;}DISPPARAMS params = { NULL, NULL, 0, 0 };hr = spShellApp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &result, NULL, NULL);if (FAILED(hr) || result.vt != VT_DISPATCH) {PrintError(L"Invoke for Windows", hr);// `spShellApp` 销毁spShellApp.Release();CoUninitialize();return 1;}CComPtr<IDispatch> spWindowsDisp = result.pdispVal;// 获取窗口集合并遍历DISPID dispidItem;OLECHAR* itemMethod = (OLECHAR*)L"Item";hr = spWindowsDisp->GetIDsOfNames(IID_NULL, &itemMethod, 1, LOCALE_USER_DEFAULT, &dispidItem);if (FAILED(hr)) {PrintError(L"GetIDsOfNames for Item", hr);// `spShellApp` 销毁spShellApp.Release();CoUninitialize();return 1;}// 获取 Count 属性来遍历集合DISPID dispidCount;OLECHAR* countMethod = (OLECHAR*)L"Count";hr = spWindowsDisp->GetIDsOfNames(IID_NULL, &countMethod, 1, LOCALE_USER_DEFAULT, &dispidCount);if (FAILED(hr)) {PrintError(L"GetIDsOfNames for Count", hr);// `spShellApp` 销毁spShellApp.Release();CoUninitialize();return 1;}CComVariant countResult;hr = spWindowsDisp->Invoke(dispidCount, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &countResult, NULL, NULL);if (FAILED(hr) || countResult.vt != VT_I4) {PrintError(L"Invoke for Count", hr);// `spShellApp` 销毁spShellApp.Release();CoUninitialize();return 1;}long count = countResult.lVal;std::wcout << L"Number of windows found: " << count << std::endl;for (long i = 0; i < count; i++) {CComVariant index(i);CComVariant itemResult;DISPPARAMS itemParams = { &index, NULL, 1, 0 };hr = spWindowsDisp->Invoke(dispidItem, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &itemParams, &itemResult, NULL, NULL);if (FAILED(hr) || itemResult.vt != VT_DISPATCH) {PrintError(L"Invoke for Item", hr);continue;}CComPtr<IDispatch> spItemDisp = itemResult.pdispVal;// 获取路径 (LocationURL)DISPID dispidLocationURL;OLECHAR* locationMethod = (OLECHAR*)L"LocationURL";hr = spItemDisp->GetIDsOfNames(IID_NULL, &locationMethod, 1, LOCALE_USER_DEFAULT, &dispidLocationURL);if (SUCCEEDED(hr)) {CComVariant locationResult;DISPPARAMS locationParams = { NULL, NULL, 0, 0 };hr = spItemDisp->Invoke(dispidLocationURL, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &locationParams, &locationResult, NULL, NULL);if (SUCCEEDED(hr) && locationResult.vt == VT_BSTR) {std::wstring locationPath = locationResult.bstrVal;// 解码路径(本地URL转文件路径)wchar_t decodedPath[MAX_PATH];DWORD decodedPathSize = MAX_PATH;if (SUCCEEDED(PathCreateFromUrlW(locationPath.c_str(), decodedPath, &decodedPathSize, 0))) {std::wcout << L"Opened folder: " << decodedPath << std::endl;}else {std::wcout << L"Opened folder (raw): " << locationPath << std::endl;}}}}// `spShellApp` 销毁spShellApp.Release();// 在释放所有 CComPtr 对象后调用 CoUninitialize()CoUninitialize();std::wcout << L"Program finished." << std::endl;return 0;
}
第二种:
#include <Windows.h>
#include <atlbase.h>
#include <exdisp.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <iostream>
#include <string>
#include <io.h>
#include <fcntl.h>
#include <locale.h>#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "shlwapi.lib")void InitializeConsole() {setlocale(LC_ALL, ".65001");_setmode(_fileno(stdout), _O_U8TEXT);
}void PrintError(const wchar_t* context) {std::wcerr << L"Error in " << context << L": " << GetLastError() << std::endl;
}bool DecodeUrlToPath(const std::wstring& url, std::wstring& decodedPath) {wchar_t buffer[MAX_PATH] = { 0 };DWORD bufferSize = MAX_PATH;if (FAILED(PathCreateFromUrlW(url.c_str(), buffer, &bufferSize, 0))) {PrintError(L"PathCreateFromUrlW");return false;}decodedPath = buffer;return true;
}int main() {InitializeConsole();std::wcout << L"Starting program..." << std::endl;HRESULT hr = CoInitialize(NULL);if (FAILED(hr)) {PrintError(L"CoInitialize");return 1;}std::wcout << L"COM library initialized." << std::endl;CComPtr<IShellWindows> spShellWindows;hr = spShellWindows.CoCreateInstance(CLSID_ShellWindows);if (FAILED(hr)) {PrintError(L"CoCreateInstance for IShellWindows");CoUninitialize();return 1;}std::wcout << L"IShellWindows instance created." << std::endl;long count = 0;hr = spShellWindows->get_Count(&count);if (FAILED(hr) || count == 0) {PrintError(L"get_Count");std::wcout << L"No windows found or failed to retrieve count." << std::endl;CoUninitialize();return 1;}std::wcout << L"Number of windows found: " << count << std::endl;for (long i = 0; i < count; i++) {std::wcout << L"Processing window " << i << L"..." << std::endl;CComVariant var(i);CComPtr<IDispatch> spDisp;hr = spShellWindows->Item(var, &spDisp);if (FAILED(hr) || !spDisp) {PrintError(L"Item");continue;}CComPtr<IWebBrowser2> spWebBrowser;hr = spDisp.QueryInterface(&spWebBrowser);if (FAILED(hr) || !spWebBrowser) {PrintError(L"QueryInterface for IWebBrowser2");continue;}CComBSTR bstrFullName;hr = spWebBrowser->get_FullName(&bstrFullName);if (FAILED(hr) || !bstrFullName) {PrintError(L"get_FullName");continue;}std::wstring fullName(bstrFullName, SysStringLen(bstrFullName));std::wcout << L"FullName: " << fullName << std::endl;if (fullName.find(L"explorer.exe") == std::wstring::npos) {std::wcout << L"Not an explorer window, skipping." << std::endl;continue;}CComBSTR bstrLocationURL;hr = spWebBrowser->get_LocationURL(&bstrLocationURL);if (FAILED(hr) || !bstrLocationURL) {PrintError(L"get_LocationURL");continue;}std::wstring locationURL(bstrLocationURL, SysStringLen(bstrLocationURL));std::wcout << L"Location URL: " << locationURL << std::endl;std::wstring decodedPath;if (!DecodeUrlToPath(locationURL, decodedPath)) {std::wcerr << L"Failed to decode URL: " << locationURL << std::endl;continue;}std::wcout << L"Opened folder: " << decodedPath << std::endl;}CoUninitialize();std::wcout << L"Program finished." << std::endl;return 0;
}
【转载请注明出处】