myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE7
   » Gadget für Vista
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin
» Accessoires

Ressourcen
» .NET-Glossar
» guide to C#
» openbook: Visual C#
» openbook: OO
» .NET BlogBook
» MSDN Webcasts
» dotnetjob.de
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Bankverbindung
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » .NET-Komponenten und C#-Snippets » ShellProvider - Delete, Move, Copy, Rename
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

ShellProvider - Delete, Move, Copy, Rename

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
inflames2k inflames2k ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 1.525
Entwicklungsumgebung: Visual Studio 2005 Standard
Herkunft: Riesa


inflames2k ist offline

ShellProvider - Delete, Move, Copy, Rename

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Beschreibung:

Mit der Klasse können Dateien / Ordner mittels Shell-Operationen gelöscht, verschoben und kopiert werden. Dabei werden die Windows-Standard-Dialoge für die jeweilige Operation angezeigt.

Umgesetzt habe ich die Klasse nachdem ich die Frage in  Windows Dialog zum Löschen von Ordnern aus eigenen Programm heraus benutzen gelesen habe und die Grundlegende Idee nicht schlecht fand.

Hinweis!

Die Klasse funktioniert womöglich nicht unter Windows 7. Ich habe sie damals nur auf Windows XP getestet. Auf meinem privaten Notebook (Windows 7) funktionieren die Methoden zumindest nicht.

Getestet am 16.04.2012

C#-Code:
public class ShellProvider
    {
        #region imports

        [DllImport("shell32.dll")]
        static extern int SHFileOperation([In] ref SHFILEOPSTRUCT lpFileOp);

        #endregion

        #region nested

        private enum FO_Func : uint
        {
            FO_MOVE = 0x0001,
            FO_COPY = 0x0002,
            FO_DELETE = 0x0003,
            FO_RENAME = 0x0004,
        }

        private struct SHFILEOPSTRUCT
        {
            public IntPtr hwnd;
            public Int32 wFunc;
                        [MarshalAs(UnmanagedType.LPWStr)]
            public string pFROM;
                        [MarshalAs(UnmanagedType.LPWStr)]
            public string pTo;
            public FILEOP_FLAGS_ENUM fFlags;
            public bool fAnyOperationsAborted;
            public Int32 hNameMappings;
            public string lpszProgressTitle;
        }

        private enum FILEOP_FLAGS_ENUM : ushort
        {
            FOF_MULTIDESTFILES = 0x0001,
            FOF_CONFIRMMOUSE = 0x0002,
            FOF_SILENT = 0x0004,  // don't create progress/report
            FOF_RENAMEONCOLLISION = 0x0008,
            FOF_NOCONFIRMATION = 0x0010,  // Don't prompt the user.
            FOF_WANTMAPPINGHANDLE = 0x0020,  // Fill in SHFILEOPSTRUCT.hNameMappings
            // Must be freed using SHFreeNameMappings
            FOF_ALLOWUNDO = 0x0040,
            FOF_FILESONLY = 0x0080,  // on *.*, do only files
            FOF_SIMPLEPROGRESS = 0x0100,  // means don't show names of files
            FOF_NOCONFIRMMKDIR = 0x0200,  // don't confirm making any needed dirs
            FOF_NOERRORUI = 0x0400,  // don't put up error UI
            FOF_NOCOPYSECURITYATTRIBS = 0x0800,  // dont copy NT file Security Attributes
            FOF_NORECURSION = 0x1000,  // don't recurse into directories.
            FOF_NO_CONNECTED_ELEMENTS = 0x2000,  // don't operate on connected elements.
            FOF_WANTNUKEWARNING = 0x4000,  // during delete operation, warn if nuking instead of recycling (partially overrides FOF_NOCONFIRMATION)
            FOF_NORECURSEREPARSE = 0x8000,  // treat reparse points as objects, not containers
        }

        #endregion

        #region Fields
        #endregion

        #region Properties
        #endregion

        #region Construction / Destruction
        #endregion

        #region Methods

        /// <summary>
        /// Method to delete a file or folder by shell
        /// </summary>
        /// <param name="sPath">path to the file / folder</param>
        public void Delete(string sPath, bool bMoveToBin, bool bWithDialog)
        {
            this.RunFileOperation(sPath, string.Empty, FO_Func.FO_DELETE, (bMoveToBin ? FILEOP_FLAGS_ENUM.FOF_ALLOWUNDO : 0) | (!bWithDialog ? FILEOP_FLAGS_ENUM.FOF_NOCONFIRMATION: 0));
        }

        /// <summary>
        /// Method to move a file
        /// </summary>
        /// <param name="sSource">the source path</param>
        /// <param name="sDestination">the destination path</param>
        public void Move(string sSource, string sDestination, bool bWithDialog)
        {
            this.RunFileOperation(sSource, sDestination, FO_Func.FO_MOVE, !bWithDialog ? FILEOP_FLAGS_ENUM.FOF_NOCONFIRMATION : 0);
        }

        /// <summary>
        /// Method to copy a file
        /// </summary>
        /// <param name="sSource">the source of the file</param>
        /// <param name="sDestination">the files destination</param>
        public void Copy(string sSource, string sDestination, bool bWithDialog)
        {
            this.RunFileOperation(sSource, sDestination, FO_Func.FO_COPY, !bWithDialog ? FILEOP_FLAGS_ENUM.FOF_NOCONFIRMATION : 0);
        }

        /// <summary>
        /// Method to rename a file or folder
        /// </summary>
        public void Rename(string sSource, string sDestination, bool bWithDialog)
        {
            this.RunFileOperation(sSource, sDestination, FO_Func.FO_RENAME, !bWithDialog ? FILEOP_FLAGS_ENUM.FOF_NOCONFIRMATION : 0);
        }

        /// <summary>
        /// Method to run the file operation
        /// </summary>
        /// <param name="sSource">the source file</param>
        /// <param name="sDestination">the destination file</param>
        /// <param name="func">the func</param>
        /// <param name="flags">the flags</param>
        /// <returns>result code</returns>
        private int RunFileOperation(string sSource, string sDestination, FO_Func func, FILEOP_FLAGS_ENUM flags)
        {
            SHFILEOPSTRUCT structure = new SHFILEOPSTRUCT();
            structure.hwnd = IntPtr.Zero;
            structure.wFunc = (int)func;
            structure.pFROM = sSource;
            structure.pTo = sDestination;
            structure.fFlags = flags;

            return SHFileOperation(ref structure);
        }

        #endregion
    }

Schlagwörter: Löschen mit Standard-Dialog, Shelloperationen, Windows Shell, Shell Kopiervorgang, Shell Verschieben

Dieser Beitrag wurde 5 mal editiert, zum letzten Mal von inflames2k am 16.04.2012 18:55.

08.02.2012 11:25 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
winSharp93 winSharp93 ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2918.png


Dabei seit: 19.01.2007
Beiträge: 5.711
Entwicklungsumgebung: VS 2010 Professional
Herkunft: Freiburg / Stuttgart


winSharp93 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Als kleinen Verbesserungsvorschlag solltest du noch die Rückgabewerten der API-Funktionen auswerten und entsprechend Exceptions werfen.

Zudem solltest es auch möglich sein, das Marshalling der Strings mit Attributen zu lösen, statt manuell Nullbytes anzuhängen.
08.02.2012 11:54 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
inflames2k inflames2k ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 1.525
Entwicklungsumgebung: Visual Studio 2005 Standard
Herkunft: Riesa

Themenstarter Thema begonnen von inflames2k

inflames2k ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zu den Rückgabewerten:
Ich bin mir nicht sicher, ob das sinnvoll ist. Ich habe das ganze jetzt mehrfach getestet und immer wenn es fehlschlägt, wird durch das Betriebssystem bereits eine Fehlermeldung ausgegeben. Insofern gehe ich davon aus, dass eine weitere Verarbeitung des Result-Codes hier nicht notwendig ist.

Zum Marshalling statt manueller Nullbytes:
Das werd ich heut Abend noch hinzufügen.
08.02.2012 14:42 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Cat
myCSharp.de-Mitglied

images/avatars/avatar-3070.jpg


Dabei seit: 25.10.2009
Beiträge: 453


Cat ist online

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Außerdem ist Delete noch falsch implementiert bei bMoveToBin = true und bWithDialog = false (dafür gibt es den |= Operator Zunge raus ).
08.02.2012 14:44 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
1mannlan 1mannlan ist männlich
myCSharp.de-Mitglied

Dabei seit: 30.09.2009
Beiträge: 88
Entwicklungsumgebung: Visual Studio 2012 Ultimate
Herkunft: Deutschland, Bayreuth


1mannlan ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Es scheint auch, als würde moveToBin nicht richtig funktionieren, auf der  Verschieben von Dateien in den Papierkorb wird auch darauf hingewiesen, das man mit diesem Flag aufpassen muss (Vollständiger Pfadname?!). Das ändern des Flags bringt zumindest beim angeben von Ordnern, die gelöscht werden sollen, keinen Unterschied.
08.02.2012 15:21 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
inflames2k inflames2k ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 1.525
Entwicklungsumgebung: Visual Studio 2005 Standard
Herkunft: Riesa

Themenstarter Thema begonnen von inflames2k

inflames2k ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich habe die offensichtlichen Fehler korrigiert, und den Grundlegenden API Aufruf in eine eigene Methode gepackt.

Die Auswertung des Fehlercodes habe ich aus oben genannten Gründen erst einmal weg gelassen.

// EDIT: Die volle Flagliste ist nicht notwendig, lasse ich aber drin, falls jemand die Operationen mit anderen Flags ausführen lassen möchte.

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von inflames2k am 08.02.2012 18:43.

08.02.2012 18:27 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als ein Jahr.
Der letzte Beitrag ist älter als ein Jahr.
Antwort erstellen


© Copyright 2003-2013 myCSharp.de-Team. Alle Rechte vorbehalten. 25.05.2013 16:18