2011-11-28 16 views
7

¿Es posible obtener una lista de los archivos que están seleccionados actualmente en el Explorador de Windows desde mi aplicación C#?¿Obtiene la selección actual en WindowsExplorer desde una aplicación C#?

He investigado mucho sobre los diferentes métodos de interacción con Windows Explorer desde un lenguaje administrado como C#. Inicialmente, estaba buscando implementaciones de extensiones de shell (here y here por ejemplo), pero aparentemente esa es una mala idea dentro del código administrado, y probablemente sea demasiado para mi situación de todos modos.

A continuación, mirado en soluciones/COM PInvoke, y se encontró this article, lo que me llevó a este código:

 SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows(); 

     string filename; 
     ArrayList windows = new ArrayList(); 

     foreach(SHDocVw.InternetExplorer ie in shellWindows) 
     { 
      filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower(); 
      if(filename.Equals("explorer")) 
      { 
       Console.WriteLine("Hard Drive: {0}", ie.LocationURL); 
       windows.Add(ie); 

       var shell = new Shell32.Shell(); 
       foreach (SHDocVw.InternetExplorerMedium sw in shell.Windows()) 
       { 
        Console.WriteLine(sw.LocationURL); 
       } 

      } 
     } 

... Pero los objetos individuales InternetExplorer no tienen métodos para obtener la selección del archivo actual, aunque se pueden usar para obtener información sobre la ventana.

Luego encontré this article haciendo exactamente lo que necesitaba, pero en C++. Usando esto como punto de partida, intenté hacer una traducción agregando shell32.dll como referencia en mi proyecto. Terminé con lo siguiente:

 SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows(); 

     string filename; 
     ArrayList windows = new ArrayList(); 

     foreach(SHDocVw.InternetExplorer ie in shellWindows) 
     { 
      filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower(); 
      if(filename.Equals("explorer")) 
      { 
       Console.WriteLine("Hard Drive: {0}", ie.LocationURL); 
       windows.Add(ie); 
       var shell = (Shell32.IShellDispatch4)new Shell32.Shell(); 
       Shell32.Folder folder = shell.NameSpace(ie.LocationURL); 
       Shell32.FolderItems items = folder.Items(); 
       foreach (Shell32.FolderItem item in items) 
       { 
        ... 
       } 
      } 
     } 

Este fue un poco más cerca, porque soy capaz de obtener un objeto Folder por la ventana, y para cada elemento, pero sigo sin ver una manera de conseguir la selección actual .

Es posible que esté mirando por completo en el lugar equivocado, pero he seguido las únicas pistas que tengo. ¿Alguien puede indicarme la solución PInvoke/COM adecuada?

Respuesta

7

Finalmente encontré una solución, gracias a esta pregunta: Get selected items of folder with WinAPI.

que terminó con la siguiente, con el fin de obtener una lista de los archivos seleccionados en ese momento:

IntPtr handle = GetForegroundWindow(); 

List<string> selected = new List<string>(); 
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); 
     } 
    } 
} 

Al parecer window.Document corresponde a la vista de carpeta real dentro de la ventana del explorador, que no es muy intuitivo. Pero aparte de los nombres de variable/método engañosos, esto funciona perfectamente.

Cuestiones relacionadas