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 #?

Michael L
la source

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")
Tomasz Smykowski
la source
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);
Samuel Yang
la source
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);
Jan Croonen
la source
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 +"\"";
Adrian Hum
la source
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 +"\"";
Phillip Hustwick
la source
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);
    }
}
RandomEngy
la source
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.


la source
6

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

Paul
la source
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)
Corey
la source
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\"");
Zztri
la source
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;
    }
}
Bluescream
la source