Comment définir une instance existante de Explorer.exe pour sélectionner un fichier?

Je peux facilement obtenir que Explorer ouvre et sélectionne un fichier en utilisant les éléments suivants:

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

Cependant, lorsque j’ouvrirai le fichier suivant, j’aurai une nouvelle instance de l’explorateur. Cela pourrait amener nos utilisateurs à ouvrir des centaines d’explorateurs avant la fin d’une journée intense.

Comment puis-je le faire pour réutiliser une instance d’explorateur déjà ouverte pour sélectionner le fichier que je veux?

Visual Studio peut le faire en cliquant avec le bouton droit de la souris sur un onglet et en sélectionnant Ouvrir le dossier contenant … à condition que l’explorateur soit déjà ouvert dans le même répertoire. Comment a-t-il pu faire cela?

Pourquoi ne pas incorporer la fenêtre Explorer dans votre application à l’aide de l’object ExplorerBrowser ? De cette façon, vous pouvez simplement continuer à réutiliser la fenêtre en appelant IExplorerBrowser::BrowseToObject sur un autre dossier lorsque vous souhaitez afficher un autre dossier.

Réessayer de restaurer une fenêtre existante de l’Explorateur est problématique car vous ne savez pas ce que l’utilisateur a fait avec cette fenêtre pendant que vous ne regardiez pas. Ils ont peut-être utilisé la sous-fenêtre Dossier pour accéder à un autre dossier, puis vous vous êtes échappé pour extraire ce dossier et l’envoyer ailleurs. Ou peut-être l’ont-ils fermé! L’ouverture d’une nouvelle fenêtre de l’Explorateur est une opération incendiaire. Si vous souhaitez conserver le contrôle de la fenêtre, vous devez exercer un contrôle plus explicite (par exemple, via ExplorerBrowser ci-dessus).

Un peu tard pour la soirée, mais si vous souhaitez sélectionner un ou plusieurs fichiers dans un dossier déjà ouvert dans une fenêtre d’explorateur, vous pouvez le faire avec la méthode SHOpenFolderAndSelectItems . Cette méthode réutilise une fenêtre existante s’il en existe une ou en ouvre une nouvelle sinon.

 [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)] ssortingng name, IntPtr bindingContext, out IntPtr pidl, uint sfgaoIn, out uint psfgaoOut); public static void ShowFileInExplorer(ssortingng folderPath, ssortingng 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); } 

Cet exemple ne sélectionne qu’un fichier, mais peut être facilement étendu pour sélectionner plusieurs fichiers.

Avez-vous essayé d’obtenir une instance de la classe Process et de toujours l’utiliser pour appeler la méthode Start() ?

 Process myProcess = new Process(); ssortingng argument = @"/select, " + filePath; myProcess.StartInfo.FileName = argument; myProcess.Start(); 

Une autre approche est l’API Win32.

 SsortingngBuilder sb = new SsortingngBuilder(@"C:\temp\"); hWnd = (...) // get Handle of the Explorer's address field. SendMessage(hWnd, WM_SETTEXT, new IntPtr(sb.ToSsortingng().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) 

Dans le même but, j’utilise launchkey.exe “{F4} ^ AC: \ TEMP {ENTER}” pour envoyer le message de clé F4 et l’instance d’explorateur en cours dans le dossier c: \ TEMP.

Je l’exécute en cliquant avec le bouton droit de la souris sur un élément du menu contextuel du shell:

 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Directory\Background\shell\85TEMP] "Position"="Top" @="JUMP TO TEMP" [HKEY_CLASSES_ROOT\Directory\Background\shell\85TEMP\command] @="c:\\launchkey\\launchkey.exe \"{F4}^AC:\\TEMP{ENTER}\"" 

“JUMP TO TEMP” est affiché le nom de l’article
“85 *” existe pour laisser en ordre d’autres “sauts” dont j’ai plusieurs. Les articles sont classés en ordre inverse par nom de clé, donc par numéro devant.