Frage

Ich kann eine einzelne Datei im Windows Explorer wie folgt anzeigen und auswählen:

explorer.exe /select, "c:\path\to\file.txt"

Ich kann jedoch nicht herausfinden, wie ich mehr als eine Datei auswählen kann.Keine der Permutationen von select, die ich ausprobiert habe, funktioniert.

Notiz:Ich habe auf diesen Seiten nach Dokumenten gesucht, aber beides hat nicht geholfen.

https://support.microsoft.com/kb/314853
http://www.infocellar.com/Win98/explorer-switches.htm

War es hilfreich?

Lösung

Dies sollte mit der Shell-Funktion möglich sein SHOpenFolderAndSelectItems

BEARBEITEN

Hier ist ein Beispielcode, der zeigt, wie die Funktion in C/C++ ohne Fehlerprüfung verwendet wird:

//Directory to open
ITEMIDLIST *dir = ILCreateFromPath(_T("C:\\"));

//Items in directory to select
ITEMIDLIST *item1 = ILCreateFromPath(_T("C:\\Program Files\\"));
ITEMIDLIST *item2 = ILCreateFromPath(_T("C:\\Windows\\"));
const ITEMIDLIST* selection[] = {item1,item2};
UINT count = sizeof(selection) / sizeof(ITEMIDLIST);

//Perform selection
SHOpenFolderAndSelectItems(dir, count, selection, 0);

//Free resources
ILFree(dir);
ILFree(item1);
ILFree(item2);

Andere Tipps

Der wahre Weg, mehrere Dateien im Explorer auszuwählen, ist der nächste

Nicht verwalteter Code sieht so aus (kompiliert aus China-Codebeiträgen mit Behebung seiner Fehler)

static class NativeMethods
{
    [DllImport("shell32.dll", ExactSpelling = true)]
    public static extern int SHOpenFolderAndSelectItems(
        IntPtr pidlFolder,
        uint cidl,
        [In, MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
        uint dwFlags);

    [DllImport("shell32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr ILCreateFromPath([MarshalAs(UnmanagedType.LPTStr)] string pszPath);

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214F9-0000-0000-C000-000000000046")]
    public interface IShellLinkW
    {
        [PreserveSig]
        int GetPath(StringBuilder pszFile, int cch, [In, Out] ref WIN32_FIND_DATAW pfd, uint fFlags);

        [PreserveSig]
        int GetIDList([Out] out IntPtr ppidl);

        [PreserveSig]
        int SetIDList([In] ref IntPtr pidl);

        [PreserveSig]
        int GetDescription(StringBuilder pszName, int cch);

        [PreserveSig]
        int SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);

        [PreserveSig]
        int GetWorkingDirectory(StringBuilder pszDir, int cch);

        [PreserveSig]
        int SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);

        [PreserveSig]
        int GetArguments(StringBuilder pszArgs, int cch);

        [PreserveSig]
        int SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);

        [PreserveSig]
        int GetHotkey([Out] out ushort pwHotkey);

        [PreserveSig]
        int SetHotkey(ushort wHotkey);

        [PreserveSig]
        int GetShowCmd([Out] out int piShowCmd);

        [PreserveSig]
        int SetShowCmd(int iShowCmd);

        [PreserveSig]
        int GetIconLocation(StringBuilder pszIconPath, int cch, [Out] out int piIcon);

        [PreserveSig]
        int SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);

        [PreserveSig]
        int SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved);

        [PreserveSig]
        int Resolve(IntPtr hwnd, uint fFlags);

        [PreserveSig]
        int SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
    }

    [Serializable, StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode), BestFitMapping(false)]
    public struct WIN32_FIND_DATAW
    {
        public uint dwFileAttributes;
        public FILETIME ftCreationTime;
        public FILETIME ftLastAccessTime;
        public FILETIME ftLastWriteTime;
        public uint nFileSizeHigh;
        public uint nFileSizeLow;
        public uint dwReserved0;
        public uint dwReserved1;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string cFileName;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
        public string cAlternateFileName;
    }

    public static void OpenFolderAndSelectFiles(string folder, params string[] filesToSelect)
    {
        IntPtr dir = ILCreateFromPath(folder);

        var filesToSelectIntPtrs = new IntPtr[filesToSelect.Length];
        for (int i = 0; i < filesToSelect.Length; i++)
        {
            filesToSelectIntPtrs[i] = ILCreateFromPath(filesToSelect[i]);
        }

        SHOpenFolderAndSelectItems(dir, (uint) filesToSelect.Length, filesToSelectIntPtrs, 0);
        ReleaseComObject(dir);
        ReleaseComObject(filesToSelectIntPtrs);
    }

    private static void ReleaseComObject(params object[] comObjs)
    {
        foreach (object obj in comObjs)
        {
            if (obj != null && Marshal.IsComObject(obj))
                Marshal.ReleaseComObject(obj);
        }
    }
}

Dies ist nicht über explorer.exe möglich

Je nachdem, was Sie tatsächlich erreichen möchten, können Sie es vielleicht schaffen AutoHotKey.Es ist ein erstaunliches kostenloses Tool zur Automatisierung von Dingen, die Sie normalerweise nicht tun können.Es sollte mit Windows kommen.Dieses Skript wählt Ihre Datei aus und hebt die nächsten beiden Dateien darunter hervor, wenn Sie F12 drücken.

F12:: 
 run explorer.exe /select`, "c:\path\to\file.txt"
 SendInput {Shift Down}{Down}{Down}{Shift Up}
return

Es ist auch möglich, einfach diese beiden mittleren Zeilen in eine Textdatei einzufügen und sie dann als Parameter an autohotkey.exe zu übergeben.Sie haben auch die Möglichkeit, das Skript zu kompilieren, wodurch es zu einer eigenständigen Exe-Datei wird, die Sie aufrufen können.Funktioniert hervorragend mit einer tollen Hilfedatei.

@Orion, Es ist möglich, Autohotkey von C# aus zu verwenden.Sie können ein Autohotkey-Skript in eine eigenständige ausführbare Datei (ca. 400 KB) umwandeln, die von Ihrer C#-App gestartet werden kann (genauso, wie Sie den Explorer starten).Sie können ihm auch Befehlszeilenparameter übergeben.Es bestehen keine Laufzeitanforderungen.

Dies ist eine dieser Fragen, bei denen es sinnvoll sein kann, darüber nachzudenken, was Sie erreichen möchten und ob es eine bessere Methode gibt.

Um einen weiteren Kontext hinzuzufügen - unser Unternehmen entwickelt eine C# Client -Anwendung, mit der Benutzer Dateien laden und Dinge mit ihnen erledigen können, wie iTunes Ihre MP3 -Dateien verwaltet, ohne Ihnen die tatsächliche Datei auf der Festplatte anzuzeigen.

Es ist nützlich, eine Datei in der Anwendung auszuwählen und den Befehl „Diese Datei im Windows Explorer anzeigen“ auszuführen – das ist es, was ich erreichen möchte, und habe dies auch für einzelne Dateien getan.

Wir verfügen über eine ListView, die es Benutzern ermöglicht, mehrere Dateien innerhalb der Anwendung auszuwählen und sie zu verschieben/löschen usw.Es wäre schön, wenn dieser Befehl „Diese Datei in Windows anzeigen“ für mehrere ausgewählte Dateien funktionieren würde – zumindest, wenn sich alle Quelldateien im selben Verzeichnis befinden. Wenn dies jedoch nicht möglich ist, handelt es sich nicht um eine wichtige Funktion.

Ich nehme an, Sie können es verwenden FindWindowEx um die SysListView32 des Windows Explorers abzurufen, dann verwenden Sie SendMessage mit LVM_SETITEMSTATE um die Elemente auszuwählen.Die Schwierigkeit besteht darin, die Position der Gegenstände zu kennen ...Vielleicht LVM_FINDITEM kann hierfür verwendet werden.

Grr, das würde ich auch gerne machen.Media Player macht das, wenn Sie mehr als 2 Dateien auswählen, mit der rechten Maustaste klicken und „Dateispeicherort öffnen“ ausführen, bin mir aber nicht ganz sicher, wie (und ich habe auch keine Lust, die Zeit mit Procmon zu verbringen, um es herauszufinden).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top