![]() |
SHFileOperation abbrechen per Code
Hallo,
ich überlege gerade, ob und wie man SHFileOperation per Code abbrechen kann, also so etwas wie das Drücken des Cancel-Buttons simulieren. Leider habe ich da keine Idee und finde auch im Netz nix. Habt Ihr da eine Idee? Gruß Mattze |
AW: SHFileOperation abbrechen per Code
Offiziell haben weder SHFileOperation noch IFileOperation eine Möglichkeit dazu. Sie laufen halt auch nicht asynchron...
Den Knopfdruck zu simulieren könnte eine Möglichkeit sein - alle Fenster Deines Prozesses iterieren, dann eine Message an das Kopierfenster, oder dort nochmal iterieren und denn Button finden und daran eine Message. Da dies in einem separaten Thread erfolgen müsste (da SHFileOperation ja seinen eigenen Thread "blockiert"), zumindest unschön - finde in der MSDN zur Threadsicherheit leider den üblichen Kommentar nicht. |
AW: SHFileOperation abbrechen per Code
Erledige die Dateioperationen einfach selbst. Dann kannst du das problemlos im Hintergrund machen, abbrechen, den Fortschritt bei dir anzeigen, was immer du willst.
Ich sehe keinen Sinn darin eine solche Funktion zu nutzen, wenn du doch eigentlich genau diese Kapselung und die Vorgaben dieser Funktion gar nicht willst... |
AW: SHFileOperation abbrechen per Code
Hallo jaenicke,
Danke. Wo Du recht hast, hast Du natürlich recht. Und dann würden die Operationen sicher auch schneller laufen. Aber: 1. Mir gefällt die Windows-Anzeige eigentlich sehr gut. Vor allem auch der "Progressbar" von Win8. 2. Ich halte den Aufwand, um dass alles nachzubauen, einfach für viel zu groß. 3. Ich erfinde nicht gerne das Fahrrad, das in der Ecke steht, neu. Es mag kein Rennrad sein, aber es reicht. Es geht natürlich um den Kopie-Abbruch bei SHFileOperation in einem Thread vom Hauptprogramm aus. Es ist denkbar, dass man gerade etwas größeres kopiert, aber aus irgendeinem (hoffentlich legalem!!!) Grund das Programm beenden muss, ohne die Zeit zu haben, den Kopiervorgang vorher abzubrechen. (Vielleicht ist der auch im Hintergrund und man hat ihn schlichtweg vergessen.) Schließe ich das Programm ohne einen expliziten Abbruch des Kopiervorganges, zeigt mir FastMM4 ein Speicherleck. Nicht sooo groß, aber immerhin! Ist die Kopie fertig oder ich breche das per Cancel-Button ab, gibt es kein Speicherleck. (Übrigen etwas komisches: Starte ich das Hauptprogramm wieder, stoße die gleiche Kopie wieder an und beende das Hauptprogramm wieder vor Kopieende, gibt es kein Speicherleck! Erst nach neuem Booten wieder bei ersten Programmstart! Wieso?) (Übrigens D7 prof.) Ich würde auch lieber das neue IFileOperation nehmen, aber das kriege ich mit D7 prof. nicht hin. Es ist wohl erst ab Delphi 2010 in der Shlobj definiert. Gibt's da schon was für D7? Gruß Mattze |
AW: SHFileOperation abbrechen per Code
Zitat:
Für Delphi 7 musst du das Interface vermutlich selbst deklarieren, falls das noch niemand getan hat und irgendwo ins Netz gestellt hat. Vielleicht findest du es bei FreePascal? |
AW: SHFileOperation abbrechen per Code
Hmmm, IFileOperation ist doch zunächst nur eine Interface Deklaration, die kannst du von MS holen und umsetzen.
Alternativ kannst du auch diese Komponente importieren, dann sollte alles da sein. BTW IFileOperation nur im SingleThread verwenden, sonst das SHFileOperation |
AW: SHFileOperation abbrechen per Code
Hallo,
ist schon klar, dass es das IFileOperation erst ab Vista gibt. Ich programmiere nur noch für Win7-64 und Win8-64. Und das mit D7, also doch nur 32Bit! Aber es geht. Wegen des IFileOperation: Starting with Delphi 2010, the IFileOperation interface is defined in the ShlObj unit. It depends on quite a few other things in that unit, so it is not a quick "copy-paste" here (besides the fact that the unit is copyrighted). (Das steht unter ![]() Ich nehme also an, dass das nicht so einfach umzusetzen ist. @Sir Rufo: Welche Komponente? Steht nix da. Gruß Mattze |
AW: SHFileOperation abbrechen per Code
IFileOperation verhält sich aber anders beim automatischen Anlegen von nicht im Ziel vorhandenen Verzeichnissen. Ein Beispiel findest du
![]() |
AW: SHFileOperation abbrechen per Code
Hallo,
ich weiß, ich weiß auch, was man dagegen machen kann. Jedenfalls habe ich es gelesen. Nur, das wirklich Schlimme ist, dass es sich momentan gar nicht verhält. Siehe doch bitte die Frage! Ich möchte es erst mal nur, ganz einfach, haben für D7. Gruß Mattze |
AW: SHFileOperation abbrechen per Code
@Mattze: ist zwar schon Ewigkeiten her - aber hattest Du damals Erfolg / einen Weg für D7 gefunden?
Ich stehe gerade (ja, ja, ich weiß - 11 Jahre später :wink:) vor dem gleichen Problem. Ich habe in meinen Programmen Probleme mit ShellAPI.SHFileOperation beim Kopieren von Dateien (egal ob SHFileOperationW oder SHFileOperationA) - das blockiert manchmal ohne erkennbaren Grund im Aufruf, deswegen würde ich gerne mein Glück mit dem IFileOperation-Interface verwenden. Ich habe nur noch keine IFileOperation-Definitionen gefunden, die in D7 funktionieren (bzw. verstehe ich nicht, wie ich das selber deklarieren kann)... |
AW: SHFileOperation abbrechen per Code
|
AW: SHFileOperation abbrechen per Code
Zitat:
Ich finde bei MS das hier: ![]() Aber wie setze ich das jetzt in Delphi um? :cyclops: |
AW: SHFileOperation abbrechen per Code
Links, siehe "Dokumentation" oder "All" (steht ja netter Weise extra daneben, wo wie viel gefunden wurde)
OK, bei Interfaces ist die Online-Hilfe öfters etwas "unhandlich". Bei Funktionen sieht es "meistens" besser aus -> oben die C++-Deklaration und unten der DLLName, welches man für ie Übersetzung nach Delphi benötigt. ![]() * 2: Nja, erstmal könnte man sich das Windows-SDK/PSDK runterladen. Dort findet sich für naheu jede WinAPI die passende Header-Datei (mit der C++-Deklaration) * 1: Strg+Shift+F Filter =
Delphi-Quellcode:
oder z.B.
*.*
Delphi-Quellcode:
*.pas;*.dfm;*.inc;*.dpr;*.dpk;*.dproj;*.h;*.c;*.sql;*.txt;*.csv
Verzeichnis =
Delphi-Quellcode:
oder
$(BDS)
Delphi-Quellcode:
$(BDS)\source
oder
Delphi-Quellcode:
$(USERPROFILE)\Documents\Embarcadero\Studio\Projekte;$(BDS)\source;$(BDSCatalogRepository);$(BDSCatalogRepositoryAllUsers)
bzw. ...\Studio\Projects für's englische Delphi und ich hab's so
Delphi-Quellcode:
(inkl. ein paar eigener Verzeichnisse)
C:\Develop;$(USERPROFILE)\Documents\Embarcadero\Studio\Projekte;$(BDS)\source;$(BDSCatalogRepository);$(BDSCatalogRepositoryAllUsers);\\FranksSpeicher\Files\Develop (Fremdcodes)
* 3: dann die üblichen Verdächtigen durchsuchen, wie z.B. die JCL * 4: Und da Borland/CodeGear/Embarcadero eh nie hinterher kam, die mitgebrachten WinAPI zu aktuell zu halten und zu erweitern .... Seit Kurzem verwenden sie ein Projekt von Microsoft, womit man große Teile der WinAPI automatisch in andere Sprachen übersetzen kann. ![]() siehe GetIt
Delphi-Quellcode:
Windows API from WinMD
|
AW: SHFileOperation abbrechen per Code
Zitat:
Zitat:
Aber wie gesagt - irgendwie funktioniert das bei ActiveX / COM basierten Schnittstellen ja anders... (...und ich bin zu doof, das zu verstehen :oops:) Zitat:
Zitat:
Habe ich natürlich gemacht - aber in meinen Verzeichnissen wurde das nirgends gefunden (wie gesagt: Delphi 7!) Auch im JEDI-Projekt nicht (auch nicht im ![]() Zitat:
Das einzige, was ich diesbezüglich gefunden habe, ist der ![]() Den bekomme ich aber nicht mit meinem Delphi 7 übersetzt - und vom Quellcode her bringt es mich leider auch nicht wirklich weiter. Wie gesagt, vielleicht bin ich einfach zu blöd dafür und ich hatte gehofft, dass schon jemand vor mir die IFileOperation-Verwendung für D7 gekapselt hat; aber scheinbar nicht :cry: |
AW: SHFileOperation abbrechen per Code
Wenn ich mir jetzt bei Microsoft die Beschreibung anschaue:
![]() Da finde ich dann unten ein C++ Beispiel für die Benutzung - das müsste ich ja in Delphi umsetzen... d.h. ich benötige zuerst CoInitializeEx - verfügbar in der ComObj-Unit, dann CoCreateInstance - verfügbar ebenfall in der ComObj-Unit; oder ich verwende direkt CreateComObject aus der selben Unit... Für den CoCreateInstance-Aufruf - oder für den Cast (?) des IUnknown-Objektes, das bei CreateComObject zurück kommt) benötige ich eine Pascal Definition der IFileOperation-Schnittstelle, weil ich diese ja zurück bekomme (IFileOperation *pfo im C++ Beispiel, verwendet über das Makro IID_PPV_ARGS()):
Code:
(wie soll ich denn das umsetzen?)
extern "C++"
{ template<typename T> _Post_equal_to_(pp) _Post_satisfies_(return == pp) void** IID_PPV_ARGS_Helper(T** pp); } #define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType) In C++ ist das Interface IFileOperation so definiert:
Code:
Dafür brauche ich dann wieder eine Definition von IShellItem, das ich leider auch nicht in meinen Delphi-Quellen als Umsetzung finde;
IFileOperation : public IUnknown
{ public: virtual HRESULT STDMETHODCALLTYPE Advise( /* [in] */ __RPC__in_opt IFileOperationProgressSink *pfops, /* [out] */ __RPC__out DWORD *pdwCookie) = 0; virtual HRESULT STDMETHODCALLTYPE Unadvise( /* [in] */ DWORD dwCookie) = 0; virtual HRESULT STDMETHODCALLTYPE SetOperationFlags( /* [in] */ DWORD dwOperationFlags) = 0; virtual HRESULT STDMETHODCALLTYPE SetProgressMessage( /* [string][in] */ __RPC__in_string LPCWSTR pszMessage) = 0; virtual HRESULT STDMETHODCALLTYPE SetProgressDialog( /* [in] */ __RPC__in_opt IOperationsProgressDialog *popd) = 0; virtual HRESULT STDMETHODCALLTYPE SetProperties( /* [in] */ __RPC__in_opt IPropertyChangeArray *pproparray) = 0; virtual HRESULT STDMETHODCALLTYPE SetOwnerWindow( /* [in] */ __RPC__in HWND hwndOwner) = 0; virtual HRESULT STDMETHODCALLTYPE ApplyPropertiesToItem( /* [in] */ __RPC__in_opt IShellItem *psiItem) = 0; virtual HRESULT STDMETHODCALLTYPE ApplyPropertiesToItems( /* [in] */ __RPC__in_opt IUnknown *punkItems) = 0; virtual HRESULT STDMETHODCALLTYPE RenameItem( /* [in] */ __RPC__in_opt IShellItem *psiItem, /* [string][in] */ __RPC__in_string LPCWSTR pszNewName, /* [unique][in] */ __RPC__in_opt IFileOperationProgressSink *pfopsItem) = 0; virtual HRESULT STDMETHODCALLTYPE RenameItems( /* [in] */ __RPC__in_opt IUnknown *pUnkItems, /* [string][in] */ __RPC__in_string LPCWSTR pszNewName) = 0; virtual HRESULT STDMETHODCALLTYPE MoveItem( /* [in] */ __RPC__in_opt IShellItem *psiItem, /* [in] */ __RPC__in_opt IShellItem *psiDestinationFolder, /* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszNewName, /* [unique][in] */ __RPC__in_opt IFileOperationProgressSink *pfopsItem) = 0; virtual HRESULT STDMETHODCALLTYPE MoveItems( /* [in] */ __RPC__in_opt IUnknown *punkItems, /* [in] */ __RPC__in_opt IShellItem *psiDestinationFolder) = 0; virtual HRESULT STDMETHODCALLTYPE CopyItem( /* [in] */ __RPC__in_opt IShellItem *psiItem, /* [in] */ __RPC__in_opt IShellItem *psiDestinationFolder, /* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszCopyName, /* [unique][in] */ __RPC__in_opt IFileOperationProgressSink *pfopsItem) = 0; virtual HRESULT STDMETHODCALLTYPE CopyItems( /* [in] */ __RPC__in_opt IUnknown *punkItems, /* [in] */ __RPC__in_opt IShellItem *psiDestinationFolder) = 0; virtual HRESULT STDMETHODCALLTYPE DeleteItem( /* [in] */ __RPC__in_opt IShellItem *psiItem, /* [unique][in] */ __RPC__in_opt IFileOperationProgressSink *pfopsItem) = 0; virtual HRESULT STDMETHODCALLTYPE DeleteItems( /* [in] */ __RPC__in_opt IUnknown *punkItems) = 0; virtual HRESULT STDMETHODCALLTYPE NewItem( /* [in] */ __RPC__in_opt IShellItem *psiDestinationFolder, /* [in] */ DWORD dwFileAttributes, /* [string][in] */ __RPC__in_string LPCWSTR pszName, /* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszTemplateName, /* [unique][in] */ __RPC__in_opt IFileOperationProgressSink *pfopsItem) = 0; virtual HRESULT STDMETHODCALLTYPE PerformOperations( void) = 0; virtual HRESULT STDMETHODCALLTYPE GetAnyOperationsAborted( /* [out] */ __RPC__out BOOL *pfAnyOperationsAborted) = 0; }; Hier die C++-Definition:
Code:
Uff - und wenn ich da in der Definition irgendwas nicht korrekt umsetze, wird's beim Aufruf wahrscheinlich einfach "knallen" und ich weiß nicht warum... :?
IShellItem : public IUnknown
{ public: virtual HRESULT STDMETHODCALLTYPE BindToHandler( /* [unique][in] */ __RPC__in_opt IBindCtx *pbc, /* [in] */ __RPC__in REFGUID bhid, /* [in] */ __RPC__in REFIID riid, /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0; virtual HRESULT STDMETHODCALLTYPE GetParent( /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; virtual HRESULT STDMETHODCALLTYPE GetDisplayName( /* [in] */ SIGDN sigdnName, /* [annotation][string][out] */ _Outptr_result_nullonfailure_ LPWSTR *ppszName) = 0; virtual HRESULT STDMETHODCALLTYPE GetAttributes( /* [in] */ SFGAOF sfgaoMask, /* [out] */ __RPC__out SFGAOF *psfgaoAttribs) = 0; virtual HRESULT STDMETHODCALLTYPE Compare( /* [in] */ __RPC__in_opt IShellItem *psi, /* [in] */ SICHINTF hint, /* [out] */ __RPC__out int *piOrder) = 0; }; Mal schauen, wie /ob ich damit weiter komme... |
AW: SHFileOperation abbrechen per Code
Jupp, ich hab z.B. auf dem NAS ein Verzeichnis mit Fremdprojekten, u.A. welche von Microsoft (Downlaods oder z.B. aus GitHub)
Dann eben die beiden CatalogRepository-Verzeichnisse vom Delphi, dessen Quellcode-Verzeichnisse, meine Quellcodeverzeichnisse usw. Wie gesagt, schon kann man im Delphi, oder mit einem externen Tool, schön darin suchen Dann kann man auch den Suchbegriff im Internet wuchen (eventuell noch zwei " drumrum und womöglich noch Delphi davor schreiben) und findet z.B. C:\Program Files (x86)\Embarcadero\Studio\23.0\source\rtl\win\Winapi.ShlObj.pas (witzig, wie ein etwas aktuelleres Delphi hilfreich sein kann) oder C:\Users\%username%\Documents\Embarcadero\Studio\23.0\CatalogRepository\WindowsAPIfromWinMD-1.0\Windows.UI.Shell.pas
Delphi-Quellcode:
oder
///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifileoperation</summary>
///<remarks> ///<para>Supported since: <i>windows6.0.6000</i></para> ///</remarks> IFileOperation = interface(IUnknown) ['{947AAB5F-0A5C-4C13-B4D6-4BF7836FC9F8}'] ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-advise</summary> function Advise(pfops: IFileOperationProgressSink; out pdwCookie: Cardinal): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-unadvise</summary> function Unadvise(dwCookie: Cardinal): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-setoperationflags</summary> function SetOperationFlags(dwOperationFlags: Cardinal): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-setprogressmessage</summary> function SetProgressMessage(pszMessage: PWSTR): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-setprogressdialog</summary> function SetProgressDialog(popd: IOperationsProgressDialog): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-setproperties</summary> function SetProperties(pproparray: IPropertyChangeArray): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-setownerwindow</summary> function SetOwnerWindow(hwndOwner: HWND): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-applypropertiestoitem</summary> function ApplyPropertiesToItem(psiItem: IShellItem): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-applypropertiestoitems</summary> function ApplyPropertiesToItems(punkItems: IUnknown): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-renameitem</summary> function RenameItem(psiItem: IShellItem; pszNewName: PWSTR; pfopsItem: IFileOperationProgressSink): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-renameitems</summary> function RenameItems(pUnkItems: IUnknown; pszNewName: PWSTR): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-moveitem</summary> function MoveItem(psiItem: IShellItem; psiDestinationFolder: IShellItem; pszNewName: PWSTR; pfopsItem: IFileOperationProgressSink): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-moveitems</summary> function MoveItems(punkItems: IUnknown; psiDestinationFolder: IShellItem): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-copyitem</summary> function CopyItem(psiItem: IShellItem; psiDestinationFolder: IShellItem; pszCopyName: PWSTR; pfopsItem: IFileOperationProgressSink): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-copyitems</summary> function CopyItems(punkItems: IUnknown; psiDestinationFolder: IShellItem): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-deleteitem</summary> function DeleteItem(psiItem: IShellItem; pfopsItem: IFileOperationProgressSink): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-deleteitems</summary> function DeleteItems(punkItems: IUnknown): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-newitem</summary> function NewItem(psiDestinationFolder: IShellItem; dwFileAttributes: Cardinal; pszName: PWSTR; pszTemplateName: PWSTR; pfopsItem: IFileOperationProgressSink): HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-performoperations</summary> function PerformOperations: HRESULT; stdcall; ///<summary>Documentation: https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-getanyoperationsaborted</summary> function GetAnyOperationsAborted(out pfAnyOperationsAborted: BOOL): HRESULT; stdcall; end; ![]() uvm. |
AW: SHFileOperation abbrechen per Code
Zitat:
Zitat:
Auf jeden Fall ist der von Dir gepostete Link auf das GitHub-Projekt Gold wert. :thumb: Danke! Da ist alles drin, was das Herz begehrt - ist zwar für FPC/Lazarus geschrieben und sehr verteilt / umfangreich, aber die Umsetzung auf D7 und die Ausdünnung auf meinen Anwendungsfall bekomme ich noch hin :wink: Ist zwar mit den vielen Interfaces und Typen immer noch eine Menge (Fleiss-)Arbeit - aber ich denke, da bin ich jetzt schon auf einem guten Weg, das zu implementieren... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz