2011-11-18 15 views
8

posso facilmente ottenere Explorer per aprire e selezionare un file utilizzando il seguente:Come posso impostare un'istanza Explorer.exe esistente per selezionare un file?

string argument = @"/select, " + filePath; 
System.Diagnostics.Process.Start("explorer.exe", argument); 

Tuttavia quando vengo ad aprire il file successivo, mi metterò una nuova istanza di explorer. Ciò potrebbe portare i nostri utenti ad aprire centinaia di esploratori aperti entro la fine di una giornata intensa.

Come posso riutilizzare un'istanza di Explorer già aperta per selezionare il file che desidero?

Visual Studio può fare ciò quando si fa clic con il tasto destro su una scheda e selezionare Apri cartella contenente ... fornendo explorer già aperto nella stessa directory. Come è stato in grado di farlo?

+3

Perché devi utilizzare Explorer in primo luogo? Cosa stai cercando di ottenere? – ChrisBint

+0

Perché non utilizzare 'System.Diagnostics.Process.Start (filePath)'? In questo modo si apre il file con il programma predefinito assegnato. – Alex

+0

@ChrisBint La nostra app ha clienti. Ogni client ha una cartella in cui sono memorizzati i vari documenti. Vogliamo l'opzione per aprire explorer nella cartella client in modo che possano sfogliare/modificare/copiare ecc. I documenti dei clienti. –

risposta

3

Come su embedding the Explorer window into your application utilizzando l'oggetto ExplorerBrowser? In questo modo, puoi continuare a riutilizzare la finestra chiamando IExplorerBrowser::BrowseToObject in una cartella diversa quando desideri mostrare una cartella diversa.

Provare a rinovigorire una finestra Explorer esistente è problematico perché non si sa cosa l'utente abbia fatto con quella finestra mentre non si stava guardando. Forse hanno usato il pannello Cartella per andare in un'altra cartella, e quindi il boom hai appena estratto la cartella da sotto e l'hai inviata da qualche altra parte. O forse l'hanno chiuso! L'apertura di una nuova finestra di Explorer è un tipo di cosa ignara. Se si desidera mantenere il controllo della finestra, è necessario esercitare un controllo più esplicito (ad esempio tramite ExplorerBrowser sopra).

+0

Windows utilizza questo comportamento per riutilizzare le finestre di Explorer aperte. Ad esempio selezionando una cartella e digitando Ctrl + Invio per aprirla in una nuova finestra. Se lo fai di nuovo, non apre una nuova istanza di finestra. –

+0

Non è lo stesso che si rinnova una finestra esistente. –

+0

bene, quindi utilizzando quindi il menu contestuale in una scorciatoia (Windows 7) e facendo clic su "trova destinazione" o simile (ho versione spagnola). Se il file di destinazione si trova in una finestra aperta, Windows lo riutilizza. –

0

Hai provato a ottenere un'istanza della classe Process e l'hai sempre utilizzata per chiamare il metodo Start()?

Process myProcess = new Process(); 
string argument = @"/select, " + filePath; 

myProcess.StartInfo.FileName = argument; 
myProcess.Start(); 
+0

Questo funziona se è lo stesso percorso della chiamata precedente. Apre una nuova finestra su percorsi diversi. – Alex

+0

Secondo [la documentazione] (http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx), 'Start()' "avvia (o riutilizza) la risorsa di processo". Quindi questo implica che puoi cambiare il valore di 'myProcess.StartInfo.FileName' e chiamare di nuovo' Start() '? – Widor

+1

@Widor Questa non è una risposta, piuttosto una domanda. Senza confermare se funziona dal rispondente, è una pura speculazione. – Marek

0

Un altro approccio è il modo API Win32.

StringBuilder sb = new StringBuilder(@"C:\temp\"); 
hWnd = (...) // get Handle of the Explorer's address field. 
SendMessage(hWnd, WM_SETTEXT, new IntPtr(sb.ToString().Length), sb) 

// Set the focus to the address field

SendMessage(hWnd, WM_SETFOCUS, IntPtr.Zero, null) 
// Simulate Enter key 
SendMessage(hWnd, WM_KEYDOWN, new IntPtr(VK_RETURN), null) 
+2

Non esiste un modo portatile per ottenere il campo dell'indirizzo e non è possibile simulare in modo affidabile l'input inviando messaggi. –

+1

È possibile enumerare tutte le finestre figlio del processo di esplorazione e controllando la CLASSE, individuare il campo dell'indirizzo. Dai un'occhiata a Spy ++. – Alex

+3

La caccia per una CLASS specifica non è portatile. Il nome della classe della barra degli indirizzi è cambiato nel corso degli anni e potrebbe cambiare molto in futuro. –

1

Un po 'tardi alla festa, ma se si desidera selezionare uno o più file in una cartella già aperta in una finestra di Explorer, è possibile farlo con il metodo shell32 SHOpenFolderAndSelectItems. Quel metodo riutilizza una finestra esistente se ce n'è una, o ne apre una nuova altrimenti.

[DllImport("shell32.dll")] 
private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, uint dwFlags); 

[DllImport("shell32.dll")] 
private static extern void SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string name, IntPtr bindingContext, out IntPtr pidl, uint sfgaoIn, out uint psfgaoOut); 

public static void ShowFileInExplorer(string folderPath, string filePath) 
{ 
    Shell32.SHParseDisplayName(Path.GetFullPath(folderPath), IntPtr.Zero, out IntPtr folder, 0, out uint psfgaoOut); 

    if (folder == IntPtr.Zero) 
    { 
     return; 
    } 

    Shell32.SHParseDisplayName(Path.GetFullPath(filePath), IntPtr.Zero, out IntPtr file, 0, out psfgaoOut); 

    if (file != IntPtr.Zero) 
    { 
     IntPtr[] files = { file }; 

     Shell32.SHOpenFolderAndSelectItems(folder, (uint)files.Length, files, 0); 
     Marshal.FreeCoTaskMem(file); 
    } 

    Marshal.FreeCoTaskMem(folder); 
} 

Questo esempio seleziona solo un file, ma può essere facilmente esteso per selezionare più file.

Problemi correlati