Search code examples
c#winapiwindows-shell

Get a list of files/directories in an open Explorer window in C#


I'm trying to pull out the list of files and directories listed in an open Explorer window (in the same order as they're displayed) so that I can look through it, then set focus to a particular item.

I found this code here that allows me to get the selected items, however I'm not sure if it's possible to use this approach to get all items:

List<string> SelectedFiles() {
    string filename;
    List<string> selected = new List<string>();
    var shell = new Shell32.Shell();
    foreach (SHDocVw.InternetExplorer window in new SHDocVw.ShellWindows()) {
        filename = Path.GetFileNameWithoutExtension(window.FullName).ToLower();
        if (filename.ToLowerInvariant() == "explorer") {
             ((Shell32.IShellFolderViewDual2)window.Document).SelectItem()
            foreach (Shell32.FolderItem item in items) {
                selected.Add(item.Path);
            }
        }
    }
    return selected;
}

It looks like this Shell32 approach would also allow me to select an item programmatically, which is the other part I'm trying to accomplish. Instead of SelectedItems(), I would call SelectItem(), though I'm not sure how to use that function.

Anyone know of a way to get the list of files/directories from an open Windows Explorer window (and ideally set focus to an item)? Perhaps a P/Invoke kind of thing?


Solution

  • I was able to modify that code snippet I found to list all files/directories instead of just the selected ones.

    Here's what I ended up with:

        List<string> FilesAndFolders() {
            string filename;
            List<string> explorerItems = new List<string>();
            var shell = new Shell32.Shell();
            foreach (SHDocVw.InternetExplorer window in new SHDocVw.ShellWindows()) {
                filename = Path.GetFileNameWithoutExtension(window.FullName).ToLower();
                if (filename.ToLowerInvariant() == "explorer") {
                    Shell32.Folder folder = ((Shell32.IShellFolderViewDual2)window.Document).Folder;
                    Shell32.FolderItems items = folder.Items();
                    foreach (Shell32.FolderItem item in items) {
                        explorerItems.Add(item.Path);
                    }
                }
            }
            return explorerItems;
        }
    

    Edit:

    To select an item, you call:

    ((Shell32.IShellFolderViewDual2)window.Document).SelectItem(item, 1);

    where window is a SHDocVw.InternetExplorer, and item is a Shell32.FolderItem (from folder.Items() in the above example). To deselect, it, pass in 0 instead of 1 as the second overload.