目次

Web検索はbingがおすすめ!

ファイルをゴミ箱に移動する - SHFileOperation を利用 - C#

SHFileOperationを利用して、ファイルをゴミ箱に移動するコードを紹介します。

プログラム

UI

下図のUIを作成します。フォームにボタンを1つ配置します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace SHFileOperationDemo
{
  public partial class FormDelete : Form
  {
    public enum FileFuncFlags : uint
    {
      FO_MOVE = 0x1,
      FO_COPY = 0x2,
      FO_DELETE = 0x3,
      FO_RENAME = 0x4
    }

    [Flags]
    public enum FILEOP_FLAGS : ushort
    {
      FOF_MULTIDESTFILES = 0x1,
      FOF_CONFIRMMOUSE = 0x2,
      /// <summary>
      /// Don't create progress/report
      /// </summary>
      FOF_SILENT = 0x4,
      FOF_RENAMEONCOLLISION = 0x8,
      /// <summary>
      /// Don't prompt the user.
      /// </summary>
      FOF_NOCONFIRMATION = 0x10,
      /// <summary>
      /// Fill in SHFILEOPSTRUCT.hNameMappings.
      /// Must be freed using SHFreeNameMappings
      /// </summary>
      FOF_WANTMAPPINGHANDLE = 0x20,
      FOF_ALLOWUNDO = 0x40,
      /// <summary>
      /// On *.*, do only files
      /// </summary>
      FOF_FILESONLY = 0x80,
      /// <summary>
      /// Don't show names of files
      /// </summary>
      FOF_SIMPLEPROGRESS = 0x100,
      /// <summary>
      /// Don't confirm making any needed dirs
      /// </summary>
      FOF_NOCONFIRMMKDIR = 0x200,
      /// <summary>
      /// Don't put up error UI
      /// </summary>
      FOF_NOERRORUI = 0x400,
      /// <summary>
      /// Dont copy NT file Security Attributes
      /// </summary>
      FOF_NOCOPYSECURITYATTRIBS = 0x800,
      /// <summary>
      /// Don't recurse into directories.
      /// </summary>
      FOF_NORECURSION = 0x1000,
      /// <summary>
      /// Don't operate on connected elements.
      /// </summary>
      FOF_NO_CONNECTED_ELEMENTS = 0x2000,
      /// <summary>
      /// During delete operation, 
      /// warn if nuking instead of recycling (partially overrides FOF_NOCONFIRMATION)
      /// </summary>
      FOF_WANTNUKEWARNING = 0x4000,
      /// <summary>
      /// Treat reparse points as objects, not containers
      /// </summary>
      FOF_NORECURSEREPARSE = 0x8000
    }

    //[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    //If you use the above you may encounter an invalid memory access exception (when using ANSI
    //or see nothing (when using unicode) when you use FOF_SIMPLEPROGRESS flag.
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct SHFILEOPSTRUCT
    {
      public IntPtr hwnd;
      public FileFuncFlags wFunc;
      [MarshalAs(UnmanagedType.LPWStr)]
      public string pFrom;
      [MarshalAs(UnmanagedType.LPWStr)]
      public string pTo;
      public FILEOP_FLAGS fFlags;
      [MarshalAs(UnmanagedType.Bool)]
      public bool fAnyOperationsAborted;
      public IntPtr hNameMappings;
      [MarshalAs(UnmanagedType.LPWStr)]
      public string lpszProgressTitle;
    }

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


    public FormDelete()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      SHFILEOPSTRUCT shfos;
      shfos.hwnd = this.Handle;
      shfos.wFunc = FileFuncFlags.FO_DELETE;
      shfos.pFrom = "C:\\data-1\\*.*\0\0";
      shfos.pTo = null;
      shfos.fFlags = FILEOP_FLAGS.FOF_ALLOWUNDO;
      shfos.fAnyOperationsAborted = true;
      shfos.hNameMappings = IntPtr.Zero;
      shfos.lpszProgressTitle = null;

      SHFileOperation(ref shfos);
    }
  }
}

解説

コードの前半部分は、SHFileOperation で利用される、FileFuncFlags, FILEOP_FLAGS, SHFILEOPSTRUCT の定義になります。

  [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
  static extern int SHFileOperation([In] ref SHFILEOPSTRUCT lpFileOp);
上記のコードがSHFileOperationのインポートのコードです。

    private void button1_Click(object sender, EventArgs e)
    {
      SHFILEOPSTRUCT shfos;
      shfos.hwnd = this.Handle;
      shfos.wFunc = FileFuncFlags.FO_DELETE;
      shfos.pFrom = "C:\\data-1\\*.*\0\0";
      shfos.pTo = null;
      shfos.fFlags = FILEOP_FLAGS.FOF_ALLOWUNDO;
      shfos.fAnyOperationsAborted = true;
      shfos.hNameMappings = IntPtr.Zero;
      shfos.lpszProgressTitle = null;

      SHFileOperation(ref shfos);
    }
ボタンがクリックされたときは、上記のClickイベントハンドラのコードが実行されます。
SHFILEOPSTRUCT 構造体を準備し、ファイルの削除に関する情報を設定します。hWndにはウィンドウのハンドル、wFuncにはファイル操作の種類を指定します。今回ファイルの削除のため、"FileFuncFlags.FO_DELETE"を指定します。pFromは削除するファイル名を指定します。今回はファイルの削除のため、pToは指定する必要が無いため、nullとします。fFlagsはファイル処理のオプション、fAnyOperationsAborted は操作が中止できるかどうか、hNameMappings はファイル名のマッピング情報、lpszProgressTitleには進行状況ダイアログのタイトル名を設定します。
pFromには、ワイルドカードを指定できます。また、pFrom,の末尾は"\0"(ヌルゼロ)を2つ入れます。また、複数のファイルを指定する場合は、ファイル名を"\0"で区切ります。

準備したSHFILEOPSTRUCT 構造体をSHFileOperation()に与えて関数を呼び出すことで、ファイルの削除が開始されます。

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。[button1]をクリックします。


"c:\data-1"ディレクトリ内のファイルがごみ箱に移動され、削除されます。




ごみ箱を確認すると、ファイルがごみ箱に移動されていることもわかります。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2015-09-24
iPentec all rights reserverd.