11 Stimmen

Gibt es eine Windows-API zum programmatischen Ausschneiden/Kopieren/Einfügen von Dateien über den Windows Explorer?

Ich weiß, dass SHFileOperation kann verwendet werden, um Dateioperationen durchzuführen mit Windows Explorer Es führt jedoch nur vollständige Dateioperationen durch, bei denen sowohl die Quelle als auch das Ziel bekannt sind.

Gibt es eine API, die einer Anwendung das Ausschneiden, Kopieren oder Einfügen im Windows Explorer aus einer Anwendung heraus ermöglicht?

Um ein paar Fragen zu beantworten:

  • Die Verwendung des Windows Explorers zur Durchführung von Datei-/Ordneroperationen würde das Verschieben mehrerer Objekte erheblich vereinfachen. Dies ist besonders wichtig für das Verschieben von Ordnern und deren Inhalt, da MoveFile unterstützt das Verschieben von Ordnern auf andere Volumes nicht.

  • Die Verwendung des Windows Explorers zur Durchführung von Datei-/Ordneroperationen würde es ermöglichen, die Operationen zum Rückgängigmachungspuffer des Windows Explorers hinzuzufügen, so dass sie rückgängig gemacht werden können; andernfalls können Operationen, die mit Konsolenanwendungen/der Eingabeaufforderung durchgeführt werden, nicht rückgängig gemacht werden.

Ich bin sicher, dass ich gesehen habe, dass es möglich ist, Windows Explorer-Verben programmatisch auszuführen, aber ich kann keine Möglichkeit finden, dies für diese zu tun.

0 Stimmen

Eine schnelle Suche hier auf SO ergab diese Antwort die sich als hilfreich erweisen könnten. Es gibt eine API für den programmatischen Zugriff auf die Zwischenablage. Verwenden Sie .NET oder nativen Code?

0 Stimmen

@AdamMihalcin, hmm, ich hatte nicht daran gedacht, es mit der Zwischenablage zu hacken. Ich habe einige Tests durchgeführt und es sieht so aus, als ob zumindest Ausschneiden/Kopieren auf diese Weise möglich ist, aber ich bin nicht sicher, wie Einfügen implementiert werden würde. Eine einfache API-Funktion wäre viel netter.

0 Stimmen

Este hat bei mir funktioniert

1voto

Cody Gray Punkte 229889

Es ist schwer vorstellbar, warum es eine solche Funktion geben sollte, oder wozu sie gut sein sollte, wenn es sie gibt.

Ausschneiden/Kopieren und Einfügen sind für die Bequemlichkeit der Benutzer . Es ermöglicht ihnen, zu einem späteren Zeitpunkt etwas an einen anderen Ort zu verschieben/zu kopieren. Die Anwendung, die die Ausschneide-/Kopier- und Einfügefunktionalität implementiert, weiß möglicherweise nicht, wo die Daten letztendlich eingefügt werden sollen, aber das ist in Ordnung, denn die Benutzer noch weiß.

Aber ein Anmeldung eine Ausschneiden/Kopieren/Einfügen-Aktion macht nicht viel Sinn, denn damit der "Einfügen"-Teil funktioniert, muss die Anmeldung muss wissen, wo der Artikel eingefügt werden soll. Und wenn es das weiß, dann könnte es einfach die SHFileOperation Funktion, die Sie bereits kennen.

Wenn es Ihnen wirklich nur darum geht, dem Benutzer die Möglichkeit zu geben, ein Element auszuschneiden/zu kopieren/einzufügen, dann werden Sie die Zwischenablage verwenden wollen - genau wie Windows es tut. Wenn ein Element ausgeschnitten oder kopiert wird, wird es in der Zwischenablage abgelegt. Wenn ein Element eingefügt wird, wird der aktuelle Inhalt der Zwischenablage abgerufen. Verwenden Sie die Windows Zwischenablage-API-Funktionen um mit der Zwischenablage zu arbeiten.

2 Stimmen

Hier ist ein Beispiel: Sie sitzen an der Konsole. Sie geben ein C:\>cut foobar.txt , dann später, C:\Somewhere\Else>paste . Es ist so ähnlich wie pushd/popd .

0 Stimmen

@Syn: Ja, das ist das Ablegen von etwas in der Zwischenablage. Dafür gibt es keine spezielle API, man verwendet einfach die Funktionen für die Zwischenablage wie OpenClipboard y SetClipboardData .

0 Stimmen

Ja, und ich kann mir gut vorstellen, wie das Kopieren und Ausschneiden auf diese Weise erfolgen kann, aber ich sehe keine Möglichkeit, auf diese Weise einfügen zu können. Ich nehme an, es könnte die Zwischenablage lesen und manuell eine Datei-Operation abhängig vom DropEffect des CF_HDROP durchführen, aber das ist ziemlich chaotisch, weshalb ich gehofft hatte, dass es eine Art Verknüpfung zu den Ausschneiden/Kopieren/Einfügen-Funktionen des Explorers gibt.

1voto

Violet Giraffe Punkte 30534

Ich habe es in meinem Dateimanager implementiert, hier ist der Link zum GitHub-Quellcode für die Kopierfunktion. Einfügen ist in der Nähe.

Es funktioniert, indem es ein unsichtbares Explorer-Kontextmenü für die gewünschten Dateisystemobjekte erstellt und dann den Befehl Ausschneiden, Kopieren oder Einfügen aus diesem Menü aufruft. Es ist in C++ (weil COM), aber ich bin sicher, Sie können COM von anderen Sprachen als auch irgendwie verwenden.

bool copyObjectsToClipboard(std::vector<std::wstring> objects, void * parentWindow)
{
    ComInitializer comInitializer;

    IContextMenu * imenu = 0;
    HMENU hMenu = NULL;
    if (!prepareContextMenuForObjects(objects, parentWindow, hMenu, imenu) || !hMenu || !imenu)
        return false;

    CComInterfaceReleaser menuReleaser(imenu);

    const char command[] = "Copy";

    CMINVOKECOMMANDINFO info = { 0 };
    info.cbSize = sizeof(info);
    info.hwnd = (HWND)parentWindow;
    info.lpVerb = command;
    info.nShow = SW_SHOWNORMAL;
    const auto result = imenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);

    DestroyMenu(hMenu);

    return SUCCEEDED(result);
}

3 Stimmen

Die Zahl 26 ist nicht vertraglich festgelegt. Der Befehl 26 könnte "verschlüsseln" bedeuten, je nachdem, welche anderen Shell-Erweiterungen installiert sind. Legen Sie das Datenobjekt einfach selbst in die Zwischenablage

0 Stimmen

@RaymondChen: Ich lasse diese Software auf zahlreichen Windows-Rechnern laufen und habe noch keinen gesehen, bei dem sie versagt. Ich habe nicht die geringste Ahnung, wie ich es selbst dort einbauen könnte - mit der in der anderen Antwort erwähnten Zwischenablage-API? Wird es mit dem Explorer kompatibel sein? Wie auch immer, danke für den Hinweis. Sind die beiden anderen Zahlen vertraglich festgelegt?

0 Stimmen

Nun, zumindest rufen Sie nach dem kanonischen Namen auf, der stabil ist. Menü-Ids sind nicht vertraglich.

1voto

Waitrud_Weber Punkte 11
// https://learn.microsoft.com/ja-jp/windows/desktop/dataxchg/standard-clipboard-formats
const char* wichStandardClipboardFormatsIsAvailable()
{
    // Standard Clipboard Formats
    // CF_BITMAP            : 2
    // CF_DIB               : 8
    // CF_DIBV5             :17
    // CF_DIF               : 5
    // CF_DSPBITMAP         :0x0082
    // CF_DSPENHMETAFILE    :0x008E
    // CF_DSPMETAFILEPICT   :0x0082
    // CF_DSPTEXT           :0x0081
    // CF_ENHMETAFILE       :14
    // CF_GDIOBJFIRST       :0x0300
    // CF_GDIOBJLAST        :0x03FF
    // CF_HDROP             :15
    // CF_LOCALE            :16
    // CF_METAFILEPICT      :3
    // CF_OEMTEXT           :7
    // CF_OWNERDISPLAY      :0x0080
    // CF_PALETTE           :9
    // CF_PENDATA           :10
    // CF_PRIVATEFIRST      :0x0200
    // CF_PRIVATELAST       :0x02FF
    // CF_RIFF              :11
    // CF_SYLK              :4
    // CF_TEXT              :1
    // CF_TIFF              :6
    // CF_UNICODETEXT       :13
    // CF_PRIVATELAST       :0x02FF
    // CF_WAVE              :12

    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_BITMAP";
    }
    if ( IsClipboardFormatAvailable(CF_DIB) ) {
        return "CF_DIB";
    }
    if ( IsClipboardFormatAvailable(CF_DIBV5) ) {
        return "CF_DIBV5";
    }
    if ( IsClipboardFormatAvailable(CF_DIF) ) {
        return "CF_DIF";
    }
    if ( IsClipboardFormatAvailable(CF_DSPBITMAP) ) {
        return "CF_DSPBITMAP";
    }
    if ( IsClipboardFormatAvailable(CF_DSPENHMETAFILE) ) {
        return "CF_DSPENHMETAFILE";
    }
    if ( IsClipboardFormatAvailable(CF_DSPMETAFILEPICT) ) {
        return "CF_DSPMETAFILEPICT";
    }
    if ( IsClipboardFormatAvailable(CF_HDROP) ) {
        return "CF_HDROP";
    }
    if ( IsClipboardFormatAvailable(CF_GDIOBJFIRST) ) {
        return "CF_GDIOBJFIRST";
    }
    if ( IsClipboardFormatAvailable(CF_GDIOBJLAST) ) {
        return "CF_GDIOBJLAST";
    }
    if ( IsClipboardFormatAvailable(CF_HDROP) ) {
        return "CF_HDROP";
    }
    if ( IsClipboardFormatAvailable(CF_LOCALE) ) {
        return "CF_LOCALE";
    }
    if ( IsClipboardFormatAvailable(CF_METAFILEPICT) ) {
        return "CF_METAFILEPICT";
    }
    if ( IsClipboardFormatAvailable(CF_OEMTEXT) ) {
        return "CF_OEMTEXT";
    }
    if ( IsClipboardFormatAvailable(CF_OWNERDISPLAY) ) {
        return "CF_OWNERDISPLAY";
    }
    if ( IsClipboardFormatAvailable(CF_PALETTE) ) {
        return "CF_PALETTE";
    }
    if ( IsClipboardFormatAvailable(CF_RIFF) ) {
        return "CF_RIFF";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_SYLK";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_TEXT";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_UNICODETEXT";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_PRIVATELAST";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_WAVE";
    }

    return "CF_NOT_STANDARD";
}

https://github.com/WaitrudWeber/source_zip/blob/master/winmain-20190111.zip

  1. winmain_001.exe ausführen.
  2. Datei im Explorer kopieren.
  3. ctl und dann v drücken
  4. könnten Sie CF_HDROP sehen

Sie sehen die Funktion: wichStandardClipboardFormatsIsAvailable in winmain_001.cpp und https://learn.microsoft.com/ja-jp/Windows/desktop/dataxchg/standard-clipboard-formats

Ich habe Sie einmal falsch informiert und es tut mir sehr leid für alle.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X