Frage

Ich habe diese Klasse, die auf Nicht-64-Bit-Geräten recht gut zu funktionieren scheint.

using System;
using System.Runtime.InteropServices;

namespace DeleteToRecycleBin
{
/// <summary>
/// Send files directly to the recycle bin.
/// </summary>
public class RecybleBin
{

    /// <summary>
    /// Possible flags for the SHFileOperation method.
    /// </summary>
    [Flags]
    public enum FileOperationFlags: ushort 
    {
        /// <summary>
        /// Do not show a dialog during the process
        /// </summary>
        FOF_SILENT =                0x0004,
        /// <summary>
        /// Do not ask the user to confirm selection
        /// </summary>
        FOF_NOCONFIRMATION =        0x0010,
        /// <summary>
        /// Delete the file to the recycle bin.  (Required flag to send a file to the bin
        /// </summary>
        FOF_ALLOWUNDO =             0x0040,
        /// <summary>
        /// Do not show the names of the files or folders that are being recycled.
        /// </summary>
        FOF_SIMPLEPROGRESS =        0x0100,
        /// <summary>
        /// Surpress errors, if any occur during the process.
        /// </summary>
        FOF_NOERRORUI =             0x0400,
        /// <summary>
        /// Warn if files are too big to fit in the recycle bin and will need
        /// to be deleted completely.
        /// </summary>
        FOF_WANTNUKEWARNING =       0x4000,
    }

    /// <summary>
    /// File Operation Function Type for SHFileOperation
    /// </summary>
    public enum FileOperationType: uint
    {
        /// <summary>
        /// Move the objects
        /// </summary>
        FO_MOVE =                   0x0001,
        /// <summary>
        /// Copy the objects
        /// </summary>
        FO_COPY =                   0x0002,
        /// <summary>
        /// Delete (or recycle) the objects
        /// </summary>
        FO_DELETE =                 0x0003,
        /// <summary>
        /// Rename the object(s)
        /// </summary>
        FO_RENAME =                 0x0004,
    }



    /// <summary>
    /// SHFILEOPSTRUCT for SHFileOperation from COM
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
    private struct SHFILEOPSTRUCT
    {

        public IntPtr hwnd;
        [MarshalAs(UnmanagedType.U4)]
        public FileOperationType wFunc;
        public string pFrom;
        public string pTo;
        public FileOperationFlags fFlags;
        [MarshalAs(UnmanagedType.Bool)]
        public readonly bool fAnyOperationsAborted;
        public readonly IntPtr hNameMappings;
        public readonly string lpszProgressTitle;
    }

    [DllImport("shell32.dll", CharSet = CharSet.Auto)]
    private static extern int SHFileOperation(ref SHFILEOPSTRUCT FileOp);

    /// <summary>
    /// Send file to recycle bin
    /// </summary>
    /// <param name="path">Location of directory or file to recycle</param>
    /// <param name="flags">FileOperationFlags to add in addition to FOF_ALLOWUNDO</param>
    public static bool Send(string path, FileOperationFlags flags)
    {
        try
        {
            SHFILEOPSTRUCT fs = new SHFILEOPSTRUCT
                                    {
                                        wFunc = FileOperationType.FO_DELETE,
                                        pFrom = path + '\0' + '\0',
                                        fFlags = FileOperationFlags.FOF_ALLOWUNDO | flags
                                    };

            // important to double-terminate the string.
            SHFileOperation(ref fs);
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }

    /// <summary>
    /// Send file to recycle bin.  Display dialog, display warning if files are too big to fit (FOF_WANTNUKEWARNING)
    /// </summary>
    /// <param name="path">Location of directory or file to recycle</param>
    public static bool Send(string path) {
        return Send(path, FileOperationFlags.FOF_NOCONFIRMATION | FileOperationFlags.FOF_WANTNUKEWARNING);
    }

    /// <summary>
    /// Send file silently to recycle bin.  Surpress dialog, surpress errors, delete if too large.
    /// </summary>
    /// <param name="path">Location of directory or file to recycle</param>
    public static bool SendSilent(string path)
    {
        return Send(path, FileOperationFlags.FOF_NOCONFIRMATION | FileOperationFlags.FOF_NOERRORUI | FileOperationFlags.FOF_SILENT);

    }
}

}

Gibt es eine Möglichkeit, das Problem zu beheben, damit es auch auf x64 gut funktioniert?Ich habe versucht, ushort zu ulong und ein paar andere Modifikationen zu ändern, aber es funktioniert nicht.

Ich weiß, dass es andere Lösungen gibt, die einen Verweis auf Microsoft erfordern.VisualBasic, aber ich würde p / invoke Weg bevorzugen.

RICHTIGE ANTWORT IST:

Unter x64 muss das SHFILEOPSTRUCT ohne den Parameter Pack = 1 deklariert werden, sonst schlägt es fehl.Dies ist ein echter Schmerz, wenn Sie möchten, dass Ihr Code plattformunabhängig ist, da Sie zwei separate Strukturen deklarieren müssen, eine mit Pack = 1 und eine ohne.Sie müssen dann zwei verschiedene SHFileOperation Aufrufe deklarieren, einen für jede der Strukturen.Dann müssen Sie entscheiden, welchen Sie anrufen möchten, je nachdem, ob Sie mit 32 oder 64 Bit arbeiten.

War es hilfreich?

Lösung

Haben Sie sich die angesehen PInvoke standort?Es hat eine etwas andere Definition für den Typ FILEOPSTRUCT, wodurch Unicode für eine Sache erzwungen wird.Ich frage mich, ob der Zeichensatz = auto Dinge verwirrt...als wäre es standardmäßig ANSI auf 32 Bit, aber Unicode auf 64 Bit und irgendwo in der Mitte läuft etwas schief.

BEARBEITEN;Auch der Visual Basic-Referenzansatz ist einfach...Ich weiß, dass die Leute aus irgendeinem Grund eine Abneigung dagegen haben, aber die relevanten DLLs sind immer noch Teil des Kernframeworks, sodass Sie keine neuen Abhängigkeiten hinzufügen werden.

Andere Tipps

So seltsam es auch scheint, .NET hat bereits Funktionen zum Löschen des Recyclingbehälters ... aber sie sind in der Microsoft.VisualBasic Namespace. Speziell, Microsoft.VisualBasic.FileIO.

using Microsoft.VisualBasic.FileIO;

// class declaration, method start here

// Send file to recycle bin without dialog
FileSystem.DeleteFile("pathToFile", UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);

// Send file to recycle bin without dialog
FileSystem.DeleteFile("pathToFile", UIOption.AllDialogs, RecycleOption.SendToRecycleBin);

// Directories are the same, but with DeleteDirectory instead
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top