如何从某个驱动器打开文件夹closuresWindows资源pipe理器窗口

我在写一个小应用程序,允许用户popup(或安全删除)USB驱动器。 除了在Windows资源pipe理器中打开USB驱动器(或多个文件夹)上的文件夹时,我的应用程序工作正常。 在这种情况下popupfunction失败,因为驱动器似乎被locking。

所以我很好奇,因为用户通过我的应用程序发出一个命令来popupUSB驱动器,有没有办法让ExplorerclosuresUSB驱动器打开的窗口?

PS。 请注意,我不想closures属于Windows资源pipe理器的所有进程,但仅closures在特定驱动器上打开文件夹的进程。

Solutions Collecting From Web of "如何从某个驱动器打开文件夹closuresWindows资源pipe理器窗口"

procedure ProcessExplorerWindows(ADriveLetter: WideChar; AClose: Boolean); var ShellWindows: IShellWindows; i: Integer; Dispatch: IDispatch; WebBrowser2: IWebBrowser2; ServiceProvider: IServiceProvider; ShellBrowser: IShellBrowser; ShellView: IShellView; FolderView: IFolderView; PersistFolder2: IPersistFolder2; ItemIDList: PItemIDList; ShellFolder: IShellFolder; ChildItem: PItemIDList; Attr: DWORD; StrRet: TStrRet; FileName: UnicodeString; DesktopItemIDList: PItemIDList; begin OleCheck(CoCreateInstance(CLASS_ShellWindows, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IShellWindows, ShellWindows)); try for i := ShellWindows.Count - 1 downto 0 do begin Dispatch := ShellWindows.Item(i); try OleCheck(Dispatch.QueryInterface(IWebBrowser2, WebBrowser2)); try OleCheck(Dispatch.QueryInterface(IServiceProvider, ServiceProvider)); try OleCheck(ServiceProvider.QueryService(SID_STopLevelBrowser, IShellBrowser, ShellBrowser)); try OleCheck(ShellBrowser.QueryActiveShellView(ShellView)); try OleCheck(ShellView.QueryInterface(IFolderView, FolderView)); try OleCheck(FolderView.GetFolder(IPersistFolder2, PersistFolder2)); try OleCheck(PersistFolder2.GetCurFolder(ItemIDList)); try OleCheck(SHBindToParent(ItemIDList, IShellFolder, Pointer(ShellFolder), ChildItem)); try Attr := SFGAO_FILESYSTEM; OleCheck(ShellFolder.GetAttributesOf(1, ChildItem, Attr)); if Attr and SFGAO_FILESYSTEM = SFGAO_FILESYSTEM then begin OleCheck(ShellFolder.GetDisplayNameOf(ChildItem, SHGDN_FORPARSING, StrRet)); FileName := ''; case StrRet.uType of STRRET_WSTR: begin FileName := StrRet.pOleStr; CoTaskMemFree(StrRet.pOleStr); end; STRRET_OFFSET: if Assigned(ChildItem) then begin Inc(PByte(ChildItem), StrRet.uOffset); FileName := UnicodeString(PAnsiChar(ChildItem)); end; STRRET_CSTR: FileName := UnicodeString(AnsiString(StrRet.cStr)); end; if ExtractFileDrive(FileName) = ADriveLetter + ':' then if AClose then WebBrowser2.Quit else begin SHGetFolderLocation(0, CSIDL_DESKTOP, 0, 0, DesktopItemIDList); try OleCheck(ShellBrowser.BrowseObject(DesktopItemIDList, SBSP_SAMEBROWSER or SBSP_DEFMODE or SBSP_ABSOLUTE)); finally CoTaskMemFree(DesktopItemIDList); end; end; end; finally ShellFolder := nil; end; finally CoTaskMemFree(ItemIDList); end; finally PersistFolder2 := nil end; finally FolderView := nil; end; finally ShellView := nil; end; finally ShellBrowser := nil; end; finally ServiceProvider := nil; end; finally WebBrowser2 := nil; end; finally Dispatch := nil; end; end; finally ShellWindows := nil; end; end; 

这是@ DenisAnisimov为C ++重写的方法:

 HRESULT CloseWindowsExplorerWindowsForDrive(LPCTSTR pStrPath) { //Closes all Windows Explorer windows for a specific drive //'pStrPath' = path somewhere on the drive //RETURN: // = S_OK if done CoInitialize(NULL); HRESULT hr; TCHAR buffVolPath[MAX_PATH]; buffVolPath[0] = 0; if(GetVolumePathName(pStrPath, buffVolPath, MAX_PATH)) { int nLnVolPath = lstrlen(buffVolPath); IShellWindows* pISW = NULL; hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IShellWindows, (void**) &pISW); if (SUCCEEDED(hr)) { long nCount; if(SUCCEEDED(hr = pISW->get_Count(&nCount))) { for(int i = nCount - 1; i >= 0; i--) { CComPtr<IDispatch> pIDisp; CComVariant v_i(i); if(SUCCEEDED(hr = pISW->Item(v_i, &pIDisp))) { CComPtr<IWebBrowser2> pIWB2; if(SUCCEEDED(pIDisp->QueryInterface(IID_IWebBrowser2, (void**)&pIWB2))) { CComPtr<IServiceProvider> pISP; if(SUCCEEDED(pIDisp->QueryInterface(IID_IServiceProvider, (void**)&pISP))) { CComPtr<IShellBrowser> pIShBrswr; if(SUCCEEDED(hr= pISP->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&pIShBrswr))) { CComPtr<IShellView> pIShView; if(SUCCEEDED(hr = pIShBrswr->QueryActiveShellView(&pIShView))) { CComPtr<IFolderView> pIFV; if(SUCCEEDED(hr = pIShView->QueryInterface(IID_IFolderView, (void**)&pIFV))) { CComPtr<IPersistFolder2> pIPF2; if(SUCCEEDED(hr = pIFV->GetFolder(IID_IPersistFolder2, (void**)&pIPF2))) { LPITEMIDLIST pidlFolder = NULL; if(SUCCEEDED(hr = pIPF2->GetCurFolder(&pidlFolder))) { LPCITEMIDLIST pidlChild = NULL; CComPtr<IShellFolder> pIShFldr; if(SUCCEEDED(::SHBindToParent(pidlFolder, IID_IShellFolder, (void**)&pIShFldr, &pidlChild))) { ULONG attrs = SFGAO_FILESYSTEM; if(SUCCEEDED(hr = pIShFldr->GetAttributesOf(1, &pidlChild, &attrs))) { if(attrs & SFGAO_FILESYSTEM) { STRRET srt; if(SUCCEEDED(hr = pIShFldr->GetDisplayNameOf(pidlChild, SHGDN_FORPARSING, &srt))) { LPWSTR pStrFileName = NULL; if(SUCCEEDED(hr = StrRetToStr(&srt, pidlChild, &pStrFileName))) { //Compare to our path if(lstrlen(pStrFileName) >= nLnVolPath && ::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, buffVolPath, nLnVolPath, pStrFileName, nLnVolPath) == CSTR_EQUAL) { //Close it hr = pIWB2->Quit(); } } if(pStrFileName) { CoTaskMemFree(pStrFileName); pStrFileName = NULL; } //Free mem (if StrRetToStr() hasn't done it) if(srt.pOleStr) { CoTaskMemFree(srt.pOleStr); } } } } } //No need to free pidlChild! } if(pidlFolder) { CoTaskMemFree(pidlFolder); pidlFolder = NULL; } } } } } } } } } } pISW->Release(); } } else hr = E_INVALIDARG; CoUninitialize(); return hr; }