Explorer'da bir klasör açma ve dosya seçme


150

Ben seçili bir dosya ile explorer bir klasör açmaya çalışıyorum.

Aşağıdaki kod, istisna bulunmayan bir dosya oluşturur:

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

Bu komutu C # ile çalıştırmak için nasıl edinebilirim?

Yanıtlar:


51

Bu yöntemi kullanın :

Process.Start(String, String)

İlk argüman bir uygulamadır (explorer.exe), ikinci yöntem argümanı çalıştırdığınız uygulamanın argümanlarıdır.

Örneğin:

CMD'de:

explorer.exe -p

C # ile:

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

32
Bu Samuel Yangs cevap gibi dosyayı
seçmez

-p dosyayı seçmek için yeterli değil
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
benim için önemli :) sadece dizini
açmakla kalmadı

2
Bir cazibe gibi çalışır ama herhangi bir fikir bunu birden fazla dosya için nasıl yapabiliriz?
Pankaj

7
Küçük bir not, dosya yolumda eğik çizgi kullanılıyorsa, dosya yollu / select argümanı benim için çalışmıyor gibi görünüyor. Bu nedenle filePath = filePath.Replace ('/', '\\');
Victor Chelaru

6
Başka bir yerde belirtildiği gibi, yolunuz tırnak içine alınmalıdır - bu, virgül içeren dizin veya dosya adlarıyla ilgili sorunları önler.
Kaganar

4
Ben sorunu mücadele bazen dosya virgül içerdiğinden, yukarıdaki yaklaşım işe yaramadı. Eğer Kaganar'ın yorumunu okumasaydım, bu bana bir saatlik çalışma tasarrufu sağlayacaktı. Samuel Yang'ı yukarıdaki kodu şu şekilde değiştirmesini istiyorum: string argument = @ "/" + "\" "+ filePath +" \ ""
Wayne Lo

34

Yolunuzda virgül varsa, Process.Start (ProcessStartInfo) kullanırken tırnak işaretleri yolun çevresine yerleştirilir.

Ancak Process.Start (string, string) kullanılırken ÇALIŞMAZ. Process.Start (string, string) aslında argümanlarınızın içindeki tırnak işaretlerini kaldırır.

İşte benim için çalışan basit bir örnek.

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

Bu kabul edilen cevap olmalı. Sadece çeşitli olası arızalar (haklar sorunu, yanlış yol, vb.) İçin uygun bir istisna yönetiminden yoksundur
AF

Bu doğru cevap, kabul edilen cevap çalışmıyor, Yang'ın yanıtı da çalışmıyor.
VK

31

Sadece 2 sent değerinde, dosya adınız boşluk içeriyorsa, örneğin "c: \ Dosyam Spaces.txt İçeriyor", dosya adını tırnak işaretleri içine almanız gerekir, aksi takdirde kaşif diğer kelimelerin farklı argümanlar olduğunu varsayar ...

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

4
Aslında hayır. @Samuel Yang örneği boşluklu yollarla çalışıyor (Win7 test edildi)
Courtney Christensen

8
Phil Hustwick'in cevabını neden yine de kota koymanız gerektiğiyle ilgili cevabı okuyun
Akku

18

Samuel Yang cevabı beni harekete geçirdi, işte benim 3 sentim.

Adrian Hum haklı, dosya adınıza tırnak işareti koyduğunuzdan emin olun. Zourtney'in işaret ettiği gibi boşlukları işleyemediği için değil, dosya adlarındaki virgülleri (ve muhtemelen diğer karakterleri) ayrı argümanlar olarak tanıyacağı için. Bu yüzden Adrian Hum'un önerdiği gibi görünmeli.

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

1
Ve sağlamak için mutlaka filePathiçermiyor "içinde. Bu karakter görünüşe göre Windows sistemlerinde yasa dışıdır, ancak diğerlerinde (örneğin POSIXish sistemleri) izin verilir, bu nedenle taşınabilirlik istiyorsanız daha fazla koda ihtiyacınız vardır.
binki

14

Kullanımı Process.Startile ilgili explorer.exeolan /selectargüman tuhaf sadece az 120 karakter uzunluğunda yolları için çalışır.

Her durumda işe almak için yerel bir windows yöntemi kullanmak zorunda kaldı:

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

Bu, bir klasörü yeniden kullanmama yardımcı oldu. Process.Start ("explorer.exe", "/ select xxx") her seferinde yeni bir klasör açar!
Mitkins

bu nasıl yapılmalı, ben de sfgao için bir bayrak oluşturmak ve uint yerine bu numaralandırma geçmek
L.Trabacchin

Bu, küçük bir sorun olsa da çalışır; klasör ilk açıldığında vurgulanmaz. Bunu bir düğme tıklama yöntemi içinde çağırıyorum ve düğmeyi tekrar tıklarsam klasör açıldığında, seçilen dosyayı / klasörü vurgular. Sorun ne olabilir?
Sach

13

"/Select,c:\file.txt" kullanın

Boşluk yerine / select öğesinden sonra virgül olması gerektiğine dikkat edin.


6

Başlangıç ​​yönteminin ikinci parametresine iletilecek bağımsız değişkenleri ("/ select etc") koymanız gerekir.


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

Dosyayı bulamamasının en olası nedeni, içinde boşluk bulunan yoldur. Örneğin, "explorer / select, c: \ space space \ space.txt" dosyasını bulamaz.

Sadece yoldan önce ve sonra çift tırnak ekleyin, örneğin;

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

veya aynısını C # ile

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

1

Biraz aşırıya kaçma olabilir ama rahatlama işlevlerini seviyorum, bu yüzden bunu al:

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

Bu, <string> olarak kullandığım uzantı işlevidir .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;
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.