Abrir una carpeta en el explorador y seleccionar un archivo


150

Estoy tratando de abrir una carpeta en el explorador con un archivo seleccionado.

El siguiente código produce una excepción de archivo no encontrado:

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

¿Cómo puedo hacer que este comando se ejecute en C #?

Respuestas:


51

Usa este método :

Process.Start(String, String)

El primer argumento es una aplicación (explorer.exe), el segundo argumento del método son argumentos de la aplicación que ejecuta.

Por ejemplo:

en CMD:

explorer.exe -p

C ª#:

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

32
esto no selecciona el archivo como la respuesta de Samuel Yangs
henon

-p no es suficiente para seleccionar el archivo
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
fue significativo para mí :) no solo abrió el directorio sino que también seleccionó el archivo en particular :) gracias, saludos
InfantPro'Aravind '

2
Funciona a las mil maravillas, pero cualquier idea, ¿cómo podemos hacer eso para múltiples archivos?
Pankaj

77
Pequeña nota, el argumento / select con la ruta del archivo no parece funcionar para mí si mi ruta de archivo usa barras diagonales. Por lo tanto, tengo que hacer filePath = filePath.Replace ('/', '\\');
Victor Chelaru el

66
Como se mencionó en otra parte, su ruta debe estar entre comillas; esto evita problemas con los nombres de directorio o archivo que contienen comas.
Kaganar

44
Estaba luchando sobre el tema, a veces el enfoque anterior no funcionó porque el archivo contiene una coma. Si hubiera leído el comentario de Kaganar, me habría ahorrado una hora de trabajo. Insto a Samuel Yang a modificar el código anterior para: argumento de cadena = @ "/ select" + "\" "+ filePath +" \ ""
Wayne Lo

34

Si su ruta contiene comas, poner comillas alrededor de la ruta funcionará cuando use Process.Start (ProcessStartInfo).

Sin embargo, NO funcionará cuando se use Process.Start (string, string). Parece que Process.Start (string, string) en realidad elimina las comillas dentro de sus argumentos.

Aquí hay un ejemplo simple que funciona para mí.

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

Esta debería ser la respuesta aceptada. Simplemente carece de un manejo adecuado de excepciones para varias fallas posibles (problema de derechos, camino equivocado, etc.)
AFract

Esta es la respuesta correcta, la respuesta aceptada no funciona, la respuesta de Yang tampoco funciona.
VK

31

Solo mi valor de 2 centavos, si su nombre de archivo contiene espacios, es decir, "c: \ Mi archivo contiene espacios.txt", deberá rodear el nombre del archivo con comillas; de lo contrario, el explorador asumirá que las otras palabras son argumentos diferentes ...

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

44
En realidad, no, no lo haces. El ejemplo de @Samuel Yang funciona con caminos con espacios (probado Win7)
Courtney Christensen

8
Lea la respuesta de Phil Hustwick a continuación sobre por qué debería poner citas, sin embargo
Akku

18

La respuesta de Samuel Yang me hizo tropezar, aquí valen mis 3 centavos.

Adrian Hum tiene razón, asegúrese de poner comillas alrededor de su nombre de archivo. No porque no pueda manejar espacios como señaló Zourtney, sino porque reconocerá las comas (y posiblemente otros caracteres) en los nombres de archivos como argumentos separados. Entonces debería verse como sugirió Adrian Hum.

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

1
Y asegúrese de asegurarse de que filePathno contiene ". Este carácter es aparentemente ilegal en los sistemas Windows, pero está permitido en todos los demás (por ejemplo, sistemas POSIXish), por lo que necesita aún más código si desea portabilidad.
binki

14

El uso Process.Startde explorer.exela /selectargumentación curiosamente sólo funciona para las rutas de menos de 120 caracteres de longitud.

Tuve que usar un método nativo de Windows para que funcione en todos los casos:

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

Esto me ayudó a reutilizar una carpeta. Process.Start ("explorer.exe", "/ select xxx") abre una nueva carpeta cada vez.
Mitkins

así es como debe hacerse, también crearía una bandera para sfgao y pasaría esa enumeración en lugar de uint
L.Trabacchin

Esto funciona aunque con un pequeño problema; la primera vez que se abre la carpeta no se resalta. Llamo a esto dentro de un método de clic de botón, y una vez que la carpeta está abierta, si vuelvo a hacer clic en el botón, resalta el archivo / carpeta seleccionado. ¿Cual podría ser el problema?
Sach

13

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

Observe que debe haber una coma después / select en lugar de espacio.


6

Debe colocar los argumentos para pasar ("/ select, etc") en el segundo parámetro del método de Inicio.


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 razón más posible para que no encuentre el archivo es la ruta que tiene espacios. Por ejemplo, no encontrará "explorer / select, c: \ space space \ space.txt".

Simplemente agregue comillas dobles antes y después de la ruta, como;

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

o hacer lo mismo en C # con

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

1

Puede ser un poco exagerado, pero me gustan las funciones de conveniencia, así que toma esta:

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

Esta es la función de extensión que uso como <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;
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.