11

I need to get the current collection of files that are selected in Windows Explorer. I found the following code from here.

I'm not quite there, though. For one thing, where does GetForegroundWindow come from? And for another thing, the compiler complains on the line

var shell = new Shell32.Shell();

saying

"The type or namespace name 'Shell32' could not be found (are you missing a using directive or an assembly reference?)". I have added SHDocVw as a reference, but I still can't get past the compiler. Can someone please help me get this completed?

    IntPtr handle = GetForegroundWindow();

    ArrayList selected = new ArrayList();
    var shell = new Shell32.Shell();
    foreach(SHDocVw.InternetExplorer window in shell.Windows()) {
        if (window.HWND == (int)handle)
        {
            Shell32.FolderItems items = ((Shell32.IShellFolderViewDual2)window.Document).SelectedItems();
            foreach(Shell32.FolderItem item in items)
            {
                selected.Add(item.Path);
            }
        }
    }
Community
  • 1
  • 1
Barry Dysert
  • 665
  • 1
  • 9
  • 21
  • possible duplicate of [C#: In what assembly is SHDocVw.WebBrowser\_V1 defined?](http://stackoverflow.com/questions/3345687/c-in-what-assembly-is-shdocvw-webbrowser-v1-defined) – nawfal Jan 12 '14 at 19:29

2 Answers2

8

you don't need to get the Handle (of explorer).

In the project's references add these references found in the COM section. One needs to a reference to SHDocVw, which is the Microsoft Internet Controls COM object and Shell32, which is the Microsoft Shell Controls and Automation COM object.

Then add your:

using System.Collections;
using Shell32;
using System.IO;

Then this will work:

      string filename;  
      ArrayList selected = new ArrayList();
      foreach (SHDocVw.InternetExplorer window in new SHDocVw.ShellWindows())
      {
        filename = Path.GetFileNameWithoutExtension(window.FullName).ToLower();
        if (filename.ToLowerInvariant() == "explorer")
        {
          Shell32.FolderItems items = ((Shell32.IShellFolderViewDual2)window.Document).SelectedItems();
          foreach (Shell32.FolderItem item in items)
          {
            selected.Add(item.Path);
          }
        }
      }
peterflynn
  • 4,667
  • 2
  • 27
  • 40
Daro
  • 1,990
  • 2
  • 16
  • 22
  • This looks better, except I'm having another compile issue: – Barry Dysert Jan 07 '13 at 12:31
  • The compile issue is: Interop type 'SHDocVw.ShellWindowsClass' cannot be embedded. Use the applicable interface instead. – Barry Dysert Jan 07 '13 at 12:32
  • 1
    I changed ShellWindowsClass to just ShellWindows and it seems to be working. Thanks all! – Barry Dysert Jan 07 '13 at 12:45
  • I've edited the answer to fix the "cannot be embedded" issue. Answer https://stackoverflow.com/a/4174056/1172352 has an explanation of why ShellWindows is more correct than ShellWindowsClass. – peterflynn Apr 27 '20 at 01:45
1

The GetForegroundWindow is a Win32 API function and to use it, you need to import it as explained here: getforegroundwindow (user32)

Shell32 is described here:

working with shell 32 in C#

Finally, I do not know your task, but usually if it is necessary to select some files and get access to this collection, it is necessary to use the FileOpenDialog

Community
  • 1
  • 1
platon
  • 5,310
  • 1
  • 22
  • 24
  • Thanks to your help, I got the program to compile, but it doesn't seem to work. In fact, I'm wondering how could it? When I get the Foreground window, won't that return the handle of the window of where my program is running instead of the window where Windows Explorer has my list of selected files? – Barry Dysert Jan 07 '13 at 12:30
  • The GetForegroundWindow method retrieves a handle to the foreground window (the window with which the user is currently working). So, I do not know how your application is supposed to work. If you need to enumerate all windows, please refer to the http://www.codeproject.com/Articles/2286/Window-Hiding-with-C project. – platon Jan 07 '13 at 12:47