Mở một thư mục trong explorer và chọn một tệp


150

Tôi đang cố mở một thư mục trong explorer với một tệp được chọn.

Đoạn mã sau tạo ra một tệp không tìm thấy ngoại lệ:

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

Làm thế nào tôi có thể nhận lệnh này để thực thi trong C #?

Câu trả lời:


51

Sử dụng phương pháp này :

Process.Start(String, String)

Đối số đầu tiên là một ứng dụng (explorer.exe), đối số phương thức thứ hai là đối số của ứng dụng bạn chạy.

Ví dụ:

trong CMD:

explorer.exe -p

trong C #:

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

32
Điều này không chọn tệp như câu trả lời của Samuel Yangs
henon

-p là không đủ để chọn tệp
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
nó rất có ý nghĩa đối với tôi :) nó không chỉ mở thư mục mà còn chọn cả tệp cụ thể :) cảm ơn liên quan
InfantPro'Aravind '

2
Nó hoạt động như một bùa mê nhưng bất kỳ ý tưởng nào chúng ta có thể làm điều đó cho nhiều tệp?
Pankaj

7
Lưu ý nhỏ, đối số / select với đường dẫn tệp dường như không hoạt động đối với tôi nếu đường dẫn tệp của tôi sử dụng dấu gạch chéo về phía trước. Do đó tôi phải làm filePath = filePath.Replace ('/', '\\');
Victor Chelaru

6
Như đã đề cập ở nơi khác, đường dẫn của bạn nên được chứa trong dấu ngoặc kép - điều này ngăn chặn các vấn đề với tên thư mục hoặc tệp có chứa dấu phẩy.
Kaganar

4
Tôi đã đấu tranh về vấn đề này đôi khi cách tiếp cận trên không hoạt động vì tệp chứa dấu phẩy. Nếu tôi đã đọc bình luận của Kaganar, nó sẽ giúp tôi tiết kiệm được một giờ làm việc. Tôi kêu gọi Samuel Yang sửa đổi mã trên thành: chuỗi argument = @ "/ select" + "\" "+ filePath +" \ ""
Wayne Lo

34

Nếu đường dẫn của bạn chứa dấu phẩy, đặt dấu ngoặc kép quanh đường dẫn sẽ hoạt động khi sử dụng Process.Start (ProcessStartInfo).

Tuy nhiên, nó sẽ KHÔNG hoạt động khi sử dụng Process.Start (chuỗi, chuỗi). Có vẻ như Process.Start (chuỗi, chuỗi) thực sự loại bỏ các trích dẫn bên trong các đối số của bạn.

Đây là một ví dụ đơn giản phù hợp với tôi.

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

Đây phải là câu trả lời được chấp nhận. Nó chỉ thiếu một xử lý ngoại lệ thích hợp cho các lỗi khác nhau có thể xảy ra (vấn đề quyền, đường dẫn sai, v.v.)
SAU 25/8/2015

Đây là câu trả lời đúng, câu trả lời được chấp nhận không hoạt động, câu trả lời của Yang cũng không hoạt động.
VK

31

Chỉ có giá trị 2 xu của tôi, nếu tên tệp của bạn chứa khoảng trắng, tức là "c: \ Tệp của tôi chứa Spaces.txt", bạn sẽ cần bao quanh tên tệp bằng dấu ngoặc kép nếu không explorer sẽ cho rằng các từ đó là các đối số khác nhau ...

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

4
Trên thực tế, không, bạn không. Ví dụ của @Samuel Yang hoạt động với các đường dẫn có khoảng trắng (đã thử nghiệm Win7)
Courtney Christensen

8
Đọc câu trả lời của Phil Hustwick bên dưới về lý do tại sao bạn nên đặt dấu ngoặc kép xung quanh
Akku

18

Samuel Yang trả lời vấp tôi, đây là giá trị 3 xu của tôi.

Adrian Hum là đúng, hãy chắc chắn rằng bạn đặt dấu ngoặc kép xung quanh tên tệp của bạn. Không phải vì nó không thể xử lý các khoảng trắng như zourtney đã chỉ ra, mà bởi vì nó sẽ nhận ra dấu phẩy (và có thể các ký tự khác) trong tên tệp là các đối số riêng biệt. Vì vậy, nó nên trông như Adrian Hum đề nghị.

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

1
Và hãy chắc chắn để đảm bảo rằng filePathkhông chứa "trong đó. Ký tự này rõ ràng là bất hợp pháp trên các hệ thống Windows nhưng được phép trên tất cả các hệ thống khác (ví dụ: hệ thống POSIXish), vì vậy bạn cần nhiều mã hơn nếu bạn muốn tính di động.
binki

14

Sử dụng Process.Starttrên explorer.exevới/select lập luận kỳ quặc chỉ hoạt động cho con đường dài ít hơn 120 ký tự.

Tôi đã phải sử dụng một phương thức windows gốc để làm cho nó hoạt động trong mọi trường hợp:

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

Điều này giúp tôi sử dụng lại một thư mục. Process.Start ("explorer.exe", "/ select xxx") mở thư mục mới mỗi lần!
Mitkins

đây là cách nó nên được thực hiện, tôi cũng sẽ tạo một lá cờ cho sfgao và vượt qua enum đó thay vì uint
L.Trabacchin

Điều này hoạt động mặc dù với một vấn đề nhỏ; lần đầu tiên thư mục được mở, nó không được tô sáng. Tôi gọi cái này bên trong một phương thức bấm nút và một khi thư mục được mở nếu tôi nhấn vào nút đó một lần nữa, thì nó sẽ làm nổi bật tệp / thư mục đã chọn. Điều gì có thể là vấn đề?
Sach

13

Sử dụng "/select,c:\file.txt"

Lưu ý rằng nên có dấu phẩy sau / select thay vì dấu cách ..


6

Bạn cần đặt các đối số để vượt qua ("/ select etc") trong tham số thứ hai của phương thức Bắt đầu.


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

Lý do có thể nhất khiến nó không tìm thấy tệp là đường dẫn có khoảng trắng. Ví dụ: nó sẽ không tìm thấy "explorer / select, c: \ space space \ space.txt".

Chỉ cần thêm dấu ngoặc kép trước và sau đường dẫn, như;

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

hoặc làm tương tự trong C # với

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

1

Nó có thể là một chút quá mức nhưng tôi thích các chức năng convinience vì vậy hãy thực hiện điều này:

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

Đây là hàm mở rộng tôi sử dụng dưới dạng <chuỗi> .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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.