Hiện tại tôi đang sử dụng chức năng sau
file.Delete();
Nhưng làm thế nào tôi có thể sử dụng chức năng này để gửi một tệp vào thùng rác thay vì chỉ xóa nó ngay lập tức?
Hiện tại tôi đang sử dụng chức năng sau
file.Delete();
Nhưng làm thế nào tôi có thể sử dụng chức năng này để gửi một tệp vào thùng rác thay vì chỉ xóa nó ngay lập tức?
.NET Matters: IFileOperation in Windows Vista
và nó được tìm thấy trong Columns
thư mục.
FOFX_RECYCLEONDELETE = 0x00080000
cờ hoạt động và cờ đó chỉ được hỗ trợ trên Windows 8 trở lên.
Câu trả lời:
LƯU Ý: Điều này cũng không hoạt động với các ứng dụng không tương tác với giao diện người dùng như Windows Services
Trình bao bọc này có thể cung cấp cho bạn chức năng cần thiết:
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);
}
}
Sử dụng FileSystem.DeleteFile và chỉ định RecycleOption phù hợp .
Mặc dù điều này sẽ hoạt động với Ứng dụng tương tác giao diện người dùng, nhưng nó sẽ không hoạt động với các ứng dụng tương tác không phải giao diện người dùng như ứng dụng Dịch vụ Windows.
Microsoft.VisualBasic.FileIO.FileSystem
này về cơ bản giống như ví dụ được đăng ở đây bằng cách sử dụng SHFileOperation
.
IL
vậy nên tôi không bận tâm. Hợp ngữ VB gọi cùng một hàm WinAPI btw.
Microsoft.VisualBasic.Compatibility
tình cờ nhầm việc lắp ráp ? Điều đó tôi sẽ tránh. Có vẻ như nó sẽ sớm không còn được dùng nữa (nó được sử dụng trong công cụ báo cáo RDL, v.v.).
Từ MSDN :
Thêm một tham chiếu đến Microsoft.VisualBasic assembly. Lớp cần thiết được tìm thấy trong thư viện này.
Thêm câu lệnh using này vào đầu tệp using Microsoft.VisualBasic.FileIO
;
Sử dụng FileSystem.DeleteFile
để xóa một tập tin, nó có tùy chọn để chỉ định thùng rác hoặc không.
Sử dụng FileSystem.DeleteDirectory
để xóa một thư mục với tùy chọn để chỉ định gửi nó vào thùng rác hay không.
Giải pháp sau đây đơn giản hơn các giải pháp khác:
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")
}
}
Bạn có thể sử dụng các chức năng khác của thùng rác bằng thư viện này.
Đầu tiên, đừng quên thêm thư viện "Microsoft Shell Controls And Automation" (từ trình đơn COM), để có thể sử dụng Shell32
không gian tên. Nó sẽ được liên kết động với dự án của bạn, thay vì được biên dịch cùng với chương trình của bạn.
10
bằng Shell32.ShellSpecialFolderConstants.ssfBITBUCKET
. Có thể cần nhắc đến tham số thứ hai MoveHere
, liên quan đến các tùy chọn như 64 ("Giữ nguyên thông tin hoàn tác, nếu có thể"). Liên kết một số nguồn tài liệu từ MSDN sẽ là một kết thúc tốt đẹp.
Thật không may, bạn cần phải dùng đến API Win32 để xóa tệp vào Thùng rác. Hãy thử mã sau, dựa trên bài đăng này . Nó sử dụng SHFileOperation
chức năng chung cho các hoạt động của hệ thống tệp thông qua Windows Shell.
Xác định những điều sau (trong một lớp tiện ích có lẽ là tốt nhất).
[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
Và để sử dụng nó để xóa một tệp, gửi nó vào Thùng rác, bạn cần một cái gì đó như:
var shf = new SHFILEOPSTRUCT();
shf.wFunc = FO_DELETE;
shf.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
shf.pFrom = @"C:\test.txt";
SHFileOperation(ref shf);
shf.pFrom = @"C:\test.txt";
là sai - pFrom phải được kết thúc bằng kép null. Bạn nên thêm \0
vào tệp shf.pFrom = "C:\\text.txt\0";
. Xem docs.microsoft.com/en-us/windows/desktop/api/shellapi/…
Bạn có thể DllImport SHFileOperation
để làm điều này.
Tôi sử dụng phương pháp mở rộng này, sau đó tôi chỉ có thể sử dụng DirectoryInfo hoặc FileInfo và xóa nó.
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);
}
}
một ví dụ về cách gọi nó có thể là:
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();
}
Có thư viện tích hợp cho việc này.
Đầu tiên hãy thêm tham chiếu Microsoft.VisualBasic Sau đó thêm mã này:
FileSystem.DeleteFile(path_of_the_file,
Microsoft.VisualBasic.FileIO.UIOption.AllDialogs,
Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin,
Microsoft.VisualBasic.FileIO.UICancelOption.ThrowException);
Tôi đã tìm thấy điều này ở đây .