Ouverture d'un dossier dans l'explorateur et sélection d'un fichier


150

J'essaye d'ouvrir un dossier dans l'explorateur avec un fichier sélectionné.

Le code suivant produit une exception de fichier introuvable:

System.Diagnostics.Process.Start(
    "explorer.exe /select," 
    + listView1.SelectedItems[0].SubItems[1].Text + "\\" 
    + listView1.SelectedItems[0].Text);

Comment puis-je exécuter cette commande en C #?

Réponses:


51

Utilisez cette méthode :

Process.Start(String, String)

Le premier argument est une application (explorer.exe), le second argument de méthode sont les arguments de l'application que vous exécutez.

Par exemple:

dans CMD:

explorer.exe -p

en C #:

Process.Start("explorer.exe", "-p")

32
cela ne sélectionne pas le fichier comme la réponse de Samuel Yangs
henon

-p ne suffit pas pour sélectionner le fichier
Jek

327
// suppose that we have a test.txt at E:\
string filePath = @"E:\test.txt";
if (!File.Exists(filePath))
{
    return;
}

// combine the arguments together
// it doesn't matter if there is a space after ','
string argument = "/select, \"" + filePath +"\"";

System.Diagnostics.Process.Start("explorer.exe", argument);

1
c'était important pour moi :) non seulement il a ouvert le répertoire mais a également sélectionné le fichier particulier :) merci salutations
InfantPro'Aravind '28

2
Cela fonctionne comme un charme, mais une idée, comment pouvons-nous faire cela pour plusieurs fichiers?
Pankaj

7
Petite note, l'argument / select avec le chemin du fichier ne semble pas fonctionner pour moi si mon chemin de fichier utilise des barres obliques. Par conséquent, je dois faire filePath = filePath.Replace ('/', '\\');
Victor Chelaru

6
Comme mentionné ailleurs, votre chemin doit être entre guillemets - cela évite les problèmes avec les noms de répertoires ou de fichiers contenant des virgules.
Kaganar le

4
Je me battais sur le problème, parfois l'approche ci-dessus ne fonctionnait pas car le fichier contient une virgule. Si j'avais lu le commentaire de Kaganar, cela m'aurait économisé une heure de travail. J'exhorte Samuel Yang à modifier le code ci-dessus en: string argument = @ "/ select" + "\" "+ filePath +" \ ""
Wayne Lo

34

Si votre chemin contient des virgules, placer des guillemets autour du chemin fonctionnera lors de l'utilisation de Process.Start (ProcessStartInfo).

Cela ne fonctionnera PAS lors de l'utilisation de Process.Start (chaîne, chaîne). Il semble que Process.Start (string, string) supprime en fait les guillemets à l'intérieur de vos arguments.

Voici un exemple simple qui fonctionne pour moi.

string p = @"C:\tmp\this path contains spaces, and,commas\target.txt";
string args = string.Format("/e, /select, \"{0}\"", p);

ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "explorer";
info.Arguments = args;
Process.Start(info);

Cela devrait être la réponse acceptée. Il manque juste une gestion des exceptions appropriée pour diverses échecs possibles (problème de droits, mauvais chemin, etc.)
AFract

C'est la bonne réponse, la réponse acceptée ne fonctionne pas, la réponse de Yang ne fonctionne pas non plus.
VK

31

Juste mes 2 cents, si votre nom de fichier contient des espaces, c'est-à-dire "c: \ Mon fichier contient des espaces.txt", vous devrez entourer le nom de fichier de guillemets, sinon l'explorateur supposera que les autres mots sont des arguments différents ...

string argument = "/select, \"" + filePath +"\"";

4
En fait, non, vous ne le faites pas. L'exemple de @Samuel Yang fonctionne avec des chemins avec des espaces (testé Win7)
Courtney Christensen

8
Lisez la réponse de Phil Hustwick ci-dessous sur les raisons pour lesquelles vous devriez quand même mettre des citations
Akku

18

La réponse de Samuel Yang m'a fait trébucher, voici ma valeur de 3 cents.

Adrian Hum a raison, assurez-vous de mettre des guillemets autour de votre nom de fichier. Non pas parce qu'il ne peut pas gérer les espaces comme l'a souligné Zourtney, mais parce qu'il reconnaîtra les virgules (et éventuellement d'autres caractères) dans les noms de fichiers comme des arguments séparés. Cela devrait donc ressembler à ce qu'Adrian Hum a suggéré.

string argument = "/select, \"" + filePath +"\"";

1
Et assurez-vous que filePathcela ne contient pas ". Ce caractère est apparemment illégal sur les systèmes Windows mais autorisé sur tous les autres (par exemple, les systèmes POSIXish), vous avez donc besoin d'encore plus de code si vous voulez la portabilité.
binki

14

L' utilisation Process.Startsur explorer.exele /selectraisonnement fonctionne curieusement que pour les chemins moins de 120 caractères.

J'ai dû utiliser une méthode Windows native pour que cela fonctionne dans tous les cas:

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

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

public static void OpenFolderAndSelectItem(string folderPath, string file)
{
    IntPtr nativeFolder;
    uint psfgaoOut;
    SHParseDisplayName(folderPath, IntPtr.Zero, out nativeFolder, 0, out psfgaoOut);

    if (nativeFolder == IntPtr.Zero)
    {
        // Log error, can't find folder
        return;
    }

    IntPtr nativeFile;
    SHParseDisplayName(Path.Combine(folderPath, file), IntPtr.Zero, out nativeFile, 0, out psfgaoOut);

    IntPtr[] fileArray;
    if (nativeFile == IntPtr.Zero)
    {
        // Open the folder without the file selected if we can't find the file
        fileArray = new IntPtr[0];
    }
    else
    {
        fileArray = new IntPtr[] { nativeFile };
    }

    SHOpenFolderAndSelectItems(nativeFolder, (uint)fileArray.Length, fileArray, 0);

    Marshal.FreeCoTaskMem(nativeFolder);
    if (nativeFile != IntPtr.Zero)
    {
        Marshal.FreeCoTaskMem(nativeFile);
    }
}

Cela m'a aidé à réutiliser un dossier. Process.Start ("explorer.exe", "/ select xxx") ouvre un nouveau dossier à chaque fois!
Mitkins

voici comment cela devrait être fait, je créerais également un drapeau pour sfgao, et passerais cette énumération au lieu de uint
L.Trabacchin

Cela fonctionne bien qu'avec un petit problème; la première fois que le dossier est ouvert, il n'est pas mis en surbrillance. J'appelle cela dans une méthode de clic sur un bouton, et une fois que le dossier est ouvert si je clique à nouveau sur le bouton, il met en évidence le fichier / dossier sélectionné. Quel pourrait être le problème?
Sach

13

Utilisez "/select,c:\file.txt"

Notez qu'il devrait y avoir une virgule après / select au lieu d'un espace.


6

Vous devez mettre les arguments à passer ("/ select etc") dans le deuxième paramètre de la méthode Start.


5
string windir = Environment.GetEnvironmentVariable("windir");
if (string.IsNullOrEmpty(windir.Trim())) {
    windir = "C:\\Windows\\";
}
if (!windir.EndsWith("\\")) {
    windir += "\\";
}    

FileInfo fileToLocate = null;
fileToLocate = new FileInfo("C:\\Temp\\myfile.txt");

ProcessStartInfo pi = new ProcessStartInfo(windir + "explorer.exe");
pi.Arguments = "/select, \"" + fileToLocate.FullName + "\"";
pi.WindowStyle = ProcessWindowStyle.Normal;
pi.WorkingDirectory = windir;

//Start Process
Process.Start(pi)

5

La raison la plus probable pour laquelle il ne trouve pas le fichier est le chemin contenant des espaces. Par exemple, il ne trouvera pas "explorer / select, c: \ space space \ space.txt".

Ajoutez simplement des guillemets avant et après le chemin, comme;

explorer /select,"c:\space space\space.txt"

ou faites de même en C # avec

System.Diagnostics.Process.Start("explorer.exe","/select,\"c:\space space\space.txt\"");

1

Cela peut être un peu exagéré, mais j'aime les fonctions de commodité, alors prenez celle-ci:

    public static void ShowFileInExplorer(FileInfo file) {
        StartProcess("explorer.exe", null, "/select, "+file.FullName.Quote());
    }
    public static Process StartProcess(FileInfo file, params string[] args) => StartProcess(file.FullName, file.DirectoryName, args);
    public static Process StartProcess(string file, string workDir = null, params string[] args) {
        ProcessStartInfo proc = new ProcessStartInfo();
        proc.FileName = file;
        proc.Arguments = string.Join(" ", args);
        Logger.Debug(proc.FileName, proc.Arguments); // Replace with your logging function
        if (workDir != null) {
            proc.WorkingDirectory = workDir;
            Logger.Debug("WorkingDirectory:", proc.WorkingDirectory); // Replace with your logging function
        }
        return Process.Start(proc);
    }

C'est la fonction d'extension que j'utilise comme <string> .Quote ():

static class Extensions
{
    public static string Quote(this string text)
    {
        return SurroundWith(text, "\"");
    }
    public static string SurroundWith(this string text, string surrounds)
    {
        return surrounds + text + surrounds;
    }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.