Відкриття папки в Провіднику та вибір файлу


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
це не вибирає файл, як відповідь Семюеля Янга
henon

-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 argument = @ "/ select" + "\" "+ filePath +" \ ""
Wayne Lo

34

Якщо ваш шлях містить знаки комами, введення лапок навколо шляху буде працювати при використанні Process.Start (ProcessStartInfo).

Однак НЕ буде працювати при використанні Process.Start (string, string). Схоже, що 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

Це правильна відповідь, прийнята відповідь не працює, відповідь Ян також не працює.
ВК

31

Тільки мої 2 копійки коштують, якщо ваше ім'я файлу містить пробіли, тобто "c: \ Мій файл містить Spaces.txt", вам потрібно буде оточити ім'я файлу лапками, інакше Explorer буде вважати, що інші слова - це різні аргументи ...

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

4
Насправді, ні, ви цього не робите. Приклад @Samuel Yang працює з доріжками з пробілами (випробуваний Win7)
Кортні Крістенсен

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

18

Відповідь Самюеля Ян мене спонукав, ось мої 3 копійки коштують.

Адріан Гум має рацію, обов'язково поставте лапки навколо свого імені файлу. Не тому, що він не може обробляти пробіли, як вказував Зуртні, а тому, що він розпізнає коми (і, можливо, інші символи) у назви файлів як окремі аргументи. Тож має виглядати так, як запропонував Адріан Гум.

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

1
І обов’язково переконайтеся, що filePathйого немає ". Цей символ, очевидно, незаконний у системах Windows, але дозволений для всіх інших (наприклад, POSIXish систем), тому вам потрібно ще більше коду, якщо ви хочете переносити його.
бінкі

14

Використання Process.Startна 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"

Зверніть увагу, що після / select замість пробілу повинна бути кома.


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.