Obecnie używam następującej funkcji
file.Delete();
Ale jak mogę użyć tej funkcji, aby wysłać plik do kosza zamiast po prostu go usunąć?
Obecnie używam następującej funkcji
file.Delete();
Ale jak mogę użyć tej funkcji, aby wysłać plik do kosza zamiast po prostu go usunąć?
.NET Matters: IFileOperation in Windows Vista
i znajduje się w Columns
folderze.
FOFX_RECYCLEONDELETE = 0x00080000
flagi operacji, a ta flaga jest obsługiwana tylko w systemie Windows 8 lub nowszym.
Odpowiedzi:
UWAGA: Nie działa to również w przypadku aplikacji interaktywnych innych niż UI, takich jak usługi Windows
To opakowanie może zapewnić potrzebną funkcjonalność:
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);
}
}
Użyj FileSystem.DeleteFile i określ odpowiednią RecycleOption .
Chociaż będzie to działać z aplikacjami interaktywnymi UI, nie będzie działać z aplikacjami interaktywnymi bez interfejsu użytkownika, takimi jak aplikacja usługi Windows.
Microsoft.VisualBasic.FileIO.FileSystem
robi to w zasadzie to samo, co w przykładzie zamieszczonym tutaj przy użyciu SHFileOperation
.
IL
tak po prostu, więc nie mam nic przeciwko. Zestaw VB btw wywołuje tę samą funkcję WinAPI.
Microsoft.VisualBasic.Compatibility
przez przypadek? Tego bym unikał. Nie wygląda na to, że wkrótce zostanie wycofany (jest używany w silniku raportowania RDL itp.).
Z MSDN :
Dodaj odwołanie do zestawu Microsoft.VisualBasic. Potrzebna klasa znajduje się w tej bibliotece.
Dodaj tę instrukcję using na początku pliku using Microsoft.VisualBasic.FileIO
;
Służy FileSystem.DeleteFile
do usuwania pliku, ma możliwość określenia kosza lub nie.
Służy FileSystem.DeleteDirectory
do usuwania katalogu z możliwością określenia wysłania go do kosza, czy nie.
Poniższe rozwiązanie jest prostsze niż pozostałe:
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")
}
}
Korzystając z tej biblioteki, możesz korzystać z innych funkcji kosza.
Po pierwsze, nie zapomnij dodać biblioteki „Microsoft Shell Controls And Automation” (z menu COM), aby móc korzystać z Shell32
przestrzeni nazw. Będzie on dynamicznie połączony z Twoim projektem, zamiast być kompilowany wraz z Twoim programem.
10
przez Shell32.ShellSpecialFolderConstants.ssfBITBUCKET
. Warto wspomnieć o drugim parametrze to MoveHere
, dotyczącym opcji takich jak 64 („Zachowaj informacje o cofnięciu, jeśli to możliwe”). Łączenie niektórych źródeł dokumentacji z MSDN byłoby dobrym wykończeniem.
Niestety, aby usunąć plik z Kosza, musisz skorzystać z interfejsu API Win32. Wypróbuj następujący kod na podstawie tego postu . Wykorzystuje ogólną SHFileOperation
funkcję do operacji systemu plików za pośrednictwem powłoki systemu Windows.
Zdefiniuj następujące elementy (w klasie narzędzi jest prawdopodobnie najlepsze).
[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
Aby użyć go do usunięcia pliku, wysłania go do Kosza, potrzebujesz czegoś takiego:
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";
jest błędna - pFrom musi być zakończona podwójną wartością zerową. Należy dodać \0
w pliku shf.pFrom = "C:\\text.txt\0";
. Zobacz docs.microsoft.com/en-us/windows/desktop/api/shellapi/ ...
Możesz SHFileOperation
to zrobić za pomocą DllImport .
Jest do tego wbudowana biblioteka .
Najpierw dodaj odniesienie Microsoft.VisualBasic Następnie dodaj ten kod:
FileSystem.DeleteFile(path_of_the_file,
Microsoft.VisualBasic.FileIO.UIOption.AllDialogs,
Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin,
Microsoft.VisualBasic.FileIO.UICancelOption.ThrowException);
Znalazłem to tutaj .
Używam tej metody rozszerzenia, a następnie mogę po prostu użyć DirectoryInfo lub FileInfo i usunąć to.
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);
}
}
przykład, jak to nazwać, może wyglądać tak:
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();
}