Открытие папки в проводнике и выбор файла


150

Я пытаюсь открыть папку в проводнике с выбранным файлом.

Следующий код создает исключение для файла не найден:

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

Как я могу заставить эту команду выполняться в C #?

Ответы:


51

Используйте этот метод :

Process.Start(String, String)

Первый аргумент - это приложение (explorer.exe), второй аргумент метода - это аргументы приложения, которое вы запускаете.

Например:

в CMD:

explorer.exe -p

в C #:

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

32
это не выбирает файл как ответ
Сэмюэля Янга

-p не достаточно , чтобы выбрать файл
ЖЭК

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
это было важно для меня :) он не только открыл каталог, но и выбрал конкретный файл :) спасибо
InfantPro'Aravind '28

2
Это работает как шарм, но любая идея, как мы можем сделать это для нескольких файлов?
Панкадж

7
Небольшое примечание: аргумент / select с путем к файлу, кажется, не работает для меня, если мой путь к файлу использует косую черту. Поэтому я должен сделать filePath = filePath.Replace ('/', '\\');
Виктор Челару

6
Как упоминалось в другом месте, ваш путь должен быть заключен в кавычки - это предотвращает проблемы с именами каталогов или файлов, которые содержат запятые.
Каганар

4
Я боролся с этой проблемой, иногда вышеупомянутый подход не работал, потому что файл содержит запятую. Если бы я прочитал комментарий Каганара, это сэкономило бы мне час работы. Я призываю Самюэля Янга изменить приведенный выше код так: string arguments = @ "/ select" + "\" "+ filePath +" \ ""
Уэйн Ло

34

Если ваш путь содержит запятые, кавычки вокруг пути будут работать при использовании Process.Start (ProcessStartInfo).

Однако он НЕ будет работать при использовании Process.Start (строка, строка). Кажется, что Process.Start (строка, строка) на самом деле удаляет кавычки внутри ваших аргументов.

Вот простой пример, который работает для меня.

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

Это должен быть принятый ответ. Он просто не хватает надлежащих обработок для различных возможных сбоев (выпуск права, неверный путь, и т.д.) исключения
AFract

Это правильный ответ, принятый ответ не работает, ответ Ян также не работает.
VK

31

Просто мои 2 цента, если ваше имя файла содержит пробелы, то есть "c: \ My File Contains Spaces.txt", вам нужно будет заключить имя файла в кавычки, иначе проводник будет считать, что другие слова - это разные аргументы ...

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

4
На самом деле нет. Пример @Samuel Yang работает с путями с пробелами (проверено Win7)
Кортни Кристенсен

8
Читайте ответ Фила Хаствика ниже о том, почему вы все равно должны ставить цитаты
Акку,

18

Ответ Сэмюэля Яна сбил меня с толку, вот мои 3 цента.

Адриан Хам прав, убедитесь, что вы ставите кавычки вокруг вашего имени файла. Не потому, что он не может обрабатывать пробелы, как указывал Зортни, а потому, что он распознает запятые (и, возможно, другие символы) в именах файлов как отдельные аргументы. Так должно выглядеть, как предположил Адриан Хам.

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

1
И убедитесь, что в нем filePathничего не содержится ". Этот символ явно недопустим в системах Windows, но разрешен во всех других (например, в системах POSIXish), поэтому вам нужен еще больше кода, если вы хотите переносимости.
binki

14

Использование Process.Starton explorer.exeс /selectаргументом странным образом работает только для путей длиной менее 120 символов.

Мне пришлось использовать собственный метод Windows, чтобы заставить его работать во всех случаях:

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

Это помогло мне повторно использовать одну папку. Process.Start ("explorer.exe", "/ select xxx") каждый раз открывает новую папку!
Миткинс

это то, как это должно быть сделано, я бы также создал флаг для sfgao и передал бы это перечисление вместо uint
L.Trabacchin

Это работает, хотя с небольшой проблемой; при первом открытии папка не выделяется. Я вызываю это в методе нажатия кнопки, и когда папка открывается, если я нажимаю кнопку еще раз, она выделяет выбранный файл / папку. В чем может быть проблема?
Сач

13

Используйте "/select,c:\file.txt"

Обратите внимание, что после / выберите запятую вместо пробела.


6

Вы должны поместить передаваемые аргументы ("/ select etc") во второй параметр метода 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

Наиболее вероятная причина, по которой он не может найти файл - это путь, в котором есть пробелы. Например, он не найдет «explorer / select, c: \ space space \ space.txt».

Просто добавьте двойные кавычки до и после пути, например;

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

или сделать то же самое в C # с

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

1

Это может быть немного излишним, но мне нравятся удобные функции, поэтому возьмите это:

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

Это функция расширения, которую я использую как <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;
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.