系统相关
首页 > 系统相关> > c – 如何从特定驱动器中关闭已打开文件夹的Windows资源管理器窗口

c – 如何从特定驱动器中关闭已打开文件夹的Windows资源管理器窗口

作者:互联网

我正在编写一个小应用程序,允许用户弹出(或安全删除)USB驱动器.我的应用程序工作正常,除了在Windows资源管理器中打开USB驱动器(或多个文件夹)上的文件夹的情况.在这种情况下,弹出功能会因驱动器似乎被锁定而失败.

所以我很好奇,因为用户通过我的应用程序发出命令以弹出USB驱动器,有没有办法让资源管理器关闭那些从USB驱动器打开的窗口?

PS.请注意,我不想关闭属于Windows资源管理器的所有进程,而只关闭在特定驱动器上打开文件夹的进程.

解决方法:

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;

标签:windows-shell,windows-explorer,c,windows,winapi
来源: https://codeday.me/bug/20190830/1770482.html