ファイルをごみ箱に送る


83

現在、以下の機能を使用しています

file.Delete();

しかし、この関数を使用して、ファイルを完全に削除するのではなく、ごみ箱に送信するにはどうすればよいですか?



3
@UweKeimのリンクは無効になりました。MSDNマガジンの.chm形式バージョン(2007年12月)はここ.NET Matters: IFileOperation in Windows VistaにありColumnsます。記事は呼び出され、フォルダーにあります。
jrh 2016年

記事が.chmファイルで開かれません。このリンクは動作します:docs.microsoft.com/en-us/archive/msdn-magazine/2007/december/...
RandomEngy

またFOFX_RECYCLEONDELETE = 0x00080000、操作フラグに追加する必要があり、そのフラグはWindows8以降でのみサポートされます。
RandomEngy

回答:


52

注:これは、WindowsサービスなどのUIインタラクティブ以外のアプリでも機能しません

このラッパーは、必要な機能を提供できます。

using System.Runtime.InteropServices;

public class FileOperationAPIWrapper
    {
        /// <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)]
        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 bool fAnyOperationsAborted;
            public IntPtr hNameMappings;
            public 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
            {
                var fs = new SHFILEOPSTRUCT
                                        {
                                            wFunc = FileOperationType.FO_DELETE,
                                            pFrom = path + '\0' + '\0',
                                            fFlags = FileOperationFlags.FOF_ALLOWUNDO | flags
                                        };
                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 MoveToRecycleBin(string path)
        {
            return Send(path, FileOperationFlags.FOF_NOCONFIRMATION | FileOperationFlags.FOF_NOERRORUI | FileOperationFlags.FOF_SILENT);

        }

        private static bool deleteFile(string path, FileOperationFlags flags)
        {
            try
            {
                var fs = new SHFILEOPSTRUCT
                                        {
                                            wFunc = FileOperationType.FO_DELETE,
                                            pFrom = path + '\0' + '\0',
                                            fFlags = flags
                                        };
                SHFileOperation(ref fs);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static bool DeleteCompletelySilent(string path)
        {
            return deleteFile(path,
                              FileOperationFlags.FOF_NOCONFIRMATION | FileOperationFlags.FOF_NOERRORUI |
                              FileOperationFlags.FOF_SILENT);
        }
    }

使い方がわかりません…説明してもらえますか?
muttley91 2010

4
64ビットプラットフォーム用にコンパイルする場合はPack = 1を削除します(そうでない場合は失敗します)。Pack = 1が指定されていない場合、これは32ビットと64ビットの両方で機能します。pinvoke.net/default.aspx/Structures/SHFILEOPSTRUCT.html
ショーン

1
Pack = 1を使用すると、AccessViolationExceptionがスローされました。それを取り除くことはトリックをしました。道による64ビットWindows
P1nGu1n

1
このコードを実行するための要件は何ですか?Pack = 1を削除しましたが、それでもコンパイルされません。DllImport、DllImportAttribute、MarshalAs、MarshalAsAttribute、StructLayout、StructLayoutAttributeは名前空間として存在しません。助けてくれてありがとう:)
puretppc 2014年

1
SHFileOperationは長いパスを処理せず、MAX_PATHより長いパスで失敗します(プレフィックスが\\?\であっても)。
Melvyn 2018年

155

FileSystem.DeleteFileを使用して、適切なRecycleOptionを指定します。

これはUIインタラクティブアプリでは機能しますが、Windowsサービスアプリなどの非UIインタラクティブアプリでは機能しません。


17
@noldorinこれは完全に優れたソリューションであり、反対票を投じる価値はありません。VisualBasicライブラリへのアクセスが「醜い」理由についてのリファレンスが欲しいのですが。
jsmith 2010

7
@noldorin:特にこの場合、Microsoft.VisualBasic.FileIO.FileSystem基本的にはここに投稿されたSHFileOperation。を使用した例と同じです。
Dirk Vollmar 2010

18
@ノルドール:醜いですね。私にとって、WinAPIの方法はかなり醜いです-また、あなたは何かを台無しにすることでより良いショットを持っています。私は個人的にVB構文が嫌いですが、アセンブリではそれだけでIL構いません。VBアセンブリは、同じWinAPI関数を呼び出します。
Jaroslav Jandek 2010

7
@Noldorin:廃止されましたか?Microsoft.VisualBasic.Compatibilityたまたま組み立てを間違えたことがありますか?私避けたいもの。すぐに非推奨になるとは思われません(RDLレポートエンジンなどで使用されています)。
Jaroslav Jandek 2010

6
@Noldorin:組み込みのフレームワークアセンブリを使用することは、shell32.dllにハードスタイルのマッピングを行うよりも優れたソリューションのように見えます。フレームワークアセンブリを使用すると、変更を移植可能にし、後で進化させることができます。システムライブラリにマッピングすると、いつでも時代遅れになる可能性があります...
fredlegrain 2013

41

MSDNから:

Microsoft.VisualBasicアセンブリへの参照を追加します。必要なクラスはこのライブラリにあります。

このusingステートメントをファイルの先頭に追加しますusing Microsoft.VisualBasic.FileIO;

FileSystem.DeleteFileファイルを削除するために使用します。ごみ箱を指定するかどうかを指定するオプションがあります。

FileSystem.DeleteDirectoryディレクトリを削除し、ごみ箱に送るかどうかを指定するオプションを使用します。


Microsoct.VisualBasicを含めることの問題は、プログラムの他の場所(GetFiles()関数の一部)でのSearchOptionの使用と競合することです。
muttley91 2010

8
@rar Downvoteは、「競合のためにVisualBasicライブラリを参照できない」という質問で指定されていないため、まだ値しません。これは、コードで簡単に解決できます。stackoverflow.com/questions/1317263/...
JSMITH

1
このメソッドは内部でSHFileOperationを使用しているように見えます。これは長いパスを処理せず、MAX_PATHより長いパスで失敗します(プレフィックスが\\?\であっても)。
Melvyn 2018年

17

次の解決策は、他の解決策よりも簡単です。

using Shell32;

static class Program
{
    public static Shell shell = new Shell();
    public static Folder RecyclingBin = shell.NameSpace(10);

    static void Main()
    {
        RecyclingBin.MoveHere("PATH TO FILE/FOLDER")
    }
}

このライブラリを使用して、ごみ箱の他の機能を使用できます。

まず、Shell32名前空間を使用できるように、ライブラリ「Microsoft Shell Controls AndAutomation」(COMメニューから)を追加することを忘れないでください。プログラムと一緒にコンパイルされるのではなく、プロジェクトに動的にリンクされます。

[1]:https://i.stack.imgur.com/erV


8
最初の段落で他の回答にコメントするのではなく、ソリューションに焦点を当てた方が、回答の方が優れています。また、明確化のために私は置き換えたいです10Shell32.ShellSpecialFolderConstants.ssfBITBUCKETMoveHere64(「可能であれば元に戻す情報を保持する」)などのオプションに関して、の2番目のパラメーターについて言及する価値があるかもしれません。MSDNのいくつかのドキュメントソースをリンクすると、すばらしい仕上がりになります。
grek40 2017年

2
MoveHereの呼び出しではエラーが発生しないようです。存在しないファイルでの呼び出しは、サイレントに失敗します。また、MAX_CHARSより長いパスでは、「\\?」プレフィックスの有無にかかわらず、サイレントに失敗します...
Melvyn

13

残念ながら、ファイルをごみ箱に削除するには、Win32APIを使用する必要があります。この投稿に基づいて、次のコードを試してください。これはSHFileOperation、Windowsシェルを介したファイルシステム操作の汎用関数を利用します。

以下を定義します(ユーティリティクラスでおそらく最適です)。

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto, Pack=1)]
public struct SHFILEOPSTRUCT
{
        public IntPtr hwnd;
        [MarshalAs(UnmanagedType.U4)] public int wFunc;
        public string pFrom;
        public string pTo;
        public short fFlags;
        [MarshalAs(UnmanagedType.Bool)] public bool fAnyOperationsAborted;
        public IntPtr hNameMappings;
        public string lpszProgressTitle;
}

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

public const int FO_DELETE = 3;
public const int FOF_ALLOWUNDO = 0x40;
public const int FOF_NOCONFIRMATION = 0x10; // Don't prompt the user

また、これを使用してファイルを削除し、ごみ箱に送信するには、次のようなものが必要です。

var shf = new SHFILEOPSTRUCT();
shf.wFunc = FO_DELETE;
shf.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
shf.pFrom = @"C:\test.txt";
SHFileOperation(ref shf);

1
そしてdoublenullは文字列を終了します。
ショーンe

1
SHFileOperationは長いパスを処理せず、MAX_PATHより長いパスで失敗します(プレフィックスが\\?\であっても)。
Melvyn 2018年

この行shf.pFrom = @"C:\test.txt";が間違っていることに注意してください-pFromは二重ヌルで終了する必要があります。\0ファイルに追加する必要がありますshf.pFrom = "C:\\text.txt\0";。参照してくださいdocs.microsoft.com/en-us/windows/desktop/api/shellapi/...
lindexi


1

この拡張メソッドを使用すると、DirectoryInfoまたはFileInfoを使用してそれを削除できます。

public static class NativeMethods
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        struct SHFILEOPSTRUCT
    {
        public IntPtr hwnd;
        [MarshalAs(UnmanagedType.U4)]
        public int wFunc;
        public string pFrom;
        public string pTo;
        public short fFlags;
        [MarshalAs(UnmanagedType.Bool)]
        public bool fAnyOperationsAborted;
        public IntPtr hNameMappings;
        public string lpszProgressTitle;
    }
    private const int FO_DELETE = 0x0003;
    private const int FOF_ALLOWUNDO = 0x0040;           // Preserve undo information, if possible. 
    private const int FOF_NOCONFIRMATION = 0x0010;      // Show no confirmation dialog box to the user      


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

    static bool DeleteFileOrFolder(string path)
    {


        SHFILEOPSTRUCT fileop = new SHFILEOPSTRUCT();
        fileop.wFunc = FO_DELETE;
        fileop.pFrom = path + '\0' + '\0';            
        fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;


        var rc= SHFileOperation(ref fileop);
        return rc==0;
    }

    public static bool ToRecycleBin(this DirectoryInfo dir)
    {
        dir?.Refresh();
        if(dir is null || !dir.Exists)
        {
            return false;
        }
        else
            return DeleteFileOrFolder(dir.FullName);
    }
    public static bool ToRecycleBin(this FileInfo file)
    {
        file?.Refresh();

        if(file is null ||!file.Exists)
        {
            return false;
        }
        return DeleteFileOrFolder(file.FullName);
    }
}

それを呼び出す方法のサンプルはこれである可能性があります:

private void BtnDelete_Click(object sender, EventArgs e)
{
    if(MessageBox.Show("Are you sure you would like to delete this directory?", "Delete & Close", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
        return;

    var dir= new DirectoryInfo(directoryName);
    dir.ToRecycleBin();

}

-1

あり内蔵のライブラリこのため。

最初に参照Microsoft.VisualBasicを 追加し、次に次のコードを追加します。

FileSystem.DeleteFile(path_of_the_file,
                        Microsoft.VisualBasic.FileIO.UIOption.AllDialogs,
                        Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin,
                        Microsoft.VisualBasic.FileIO.UICancelOption.ThrowException);

私はこれをここで見つけまし

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.