2011-11-28 11 views
7

È possibile ottenere un elenco dei file attualmente selezionati in Esplora risorse dalla mia app C#?Ottieni la selezione corrente in WindowsExplorer da un'applicazione C#?

Ho svolto molte ricerche su diversi metodi di interazione con Windows Explorer da un linguaggio gestito come C#. Inizialmente, stavo guardando le implementazioni delle estensioni della shell (here e here per esempio), ma a quanto pare è una cattiva idea dal codice gestito, ed è probabilmente eccessivo per la mia situazione comunque.

Successivamente, ho guardato in soluzioni/COM PInvoke, e ha trovato this article, che mi ha portato a questo codice:

 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); 
       } 

      } 
     } 

... Ma i singoli InternetExplorer oggetti non hanno metodi per ottenere la selezione del file corrente, sebbene possano essere usati per ottenere informazioni sulla finestra.

Quindi ho trovato this article facendo esattamente ciò di cui avevo bisogno, ma in C++. Usando questo come punto di partenza, ho provato a fare qualche traduzione aggiungendo shell32.dll come riferimento nel mio progetto. Ho finito con il seguente:

 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) 
       { 
        ... 
       } 
      } 
     } 

Questo è stato un po 'più da vicino, perché sono in grado di ottenere un oggetto Folder per la finestra, e per ciascuna voce, ma io ancora non vedo un modo per ottenere la selezione corrente .

Potrei cercare completamente nel posto sbagliato, ma ho seguito gli unici contatti che ho. Qualcuno può indicarmi la soluzione PInvoke/COM appropriata?

risposta

7

Finalmente trovato una soluzione, grazie a questa domanda: Get selected items of folder with WinAPI.

ho finito con quanto segue, al fine di ottenere una lista dei file selezionati:

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); 
     } 
    } 
} 

Apparentemente window.Document corrisponde alla vista reale cartella all'interno della finestra di Explorer, che non è molto intuitivo. Ma a parte i nomi di variabili/metodi fuorvianti, questo funziona perfettamente.