有时候需要在程序复制、移动、删除文件等操作,虽然实现的方法有很多,但有些时候真的不如系统自带的界面效果来的直接省事。
好了不啰嗦了,直接看代码。这是网上找的,能用,但是有一点bug,有时候第一次复制文件会弹出目标文件夹不存在,给我整蒙了。还是贴上来,后面有我在用的封装好的类。
这是网上找的,慎用,请调试好了再上线。
public partial class Form1 : Form
{
[DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool SHFileOperation([In, Out] SHFILEOPSTRUCT str);
private const int FO_MOVE = 0x1;
private const int FO_COPY = 0x2;
private const int FO_DELETE = 0x3;
private const ushort FOF_NOCONFIRMATION = 0x10;
private const ushort FOF_ALLOWUNDO = 0x40;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class SHFILEOPSTRUCT
{
public IntPtr hwnd;
/// <summary>
/// 设置操作方式,移动:FO_MOVE,复制:FO_COPY,删除:FO_DELETE
/// </summary>
public UInt32 wFunc;
/// <summary>
/// 源文件路径
/// </summary>
public string pFrom;
/// <summary>
/// 目标文件路径
/// </summary>
public string pTo;
/// <summary>
/// 允许恢复
/// </summary>
public UInt16 fFlags;
/// <summary>
/// 监测有无中止
/// </summary>
public Int32 fAnyOperationsAborted;
public IntPtr hNameMappings;
/// <summary>
/// 设置标题
/// </summary>
public string lpszProgressTitle;
}
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(CopyFile().ToString());
}
private bool CopyFile()
{
SHFILEOPSTRUCT pm = new SHFILEOPSTRUCT();
pm.wFunc = FO_COPY;
pm.pFrom = @"F:/Office2003sp2_xunchi.exe";
pm.pTo = @"c:/a.exe";
pm.fFlags = FOF_ALLOWUNDO;//允许恢复
pm.lpszProgressTitle = "哈哈";
return !SHFileOperation(pm);
}
}
下面是我在用的。FileOperationManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using static Nonoby.FormMain;
namespace Nonoby.Helpers
{
public static class FileOperationManager
{
[DllImport("shell32.dll")]
private static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);
private struct SHFILEOPSTRUCT
{
public IntPtr hwnd;
public WFUNC wFunc;
public string pFrom;
public string pTo;
public FILEOP_FLAGS fFlags;
public bool fAnyOperationsAborted;
public IntPtr hNameMappings;
public string lpszProgressTitle;
}
private enum WFUNC
{
FO_MOVE = 0x0001,
FO_COPY = 0x0002,
FO_DELETE = 0x0003,
FO_RENAME = 0x0004
}
private enum FILEOP_FLAGS
{
FOF_MULTIDESTFILES = 0x0001, //pTo 指定了多个目标文件,而不是单个目录
FOF_CONFIRMMOUSE = 0x0002,
FOF_SILENT = 0x0044, // 不显示一个进度对话框
FOF_RENAMEONCOLLISION = 0x0008, // 碰到有抵触的名字时,自动分配前缀
FOF_NOCONFIRMATION = 0x10, // 不对用户显示提示
FOF_WANTMAPPINGHANDLE = 0x0020, // 填充 hNameMappings 字段,必须使用 SHFreeNameMappings 释放
FOF_ALLOWUNDO = 0x40, // 允许撤销
FOF_FILESONLY = 0x0080, // 使用 *.* 时, 只对文件操作
FOF_SIMPLEPROGRESS = 0x0100, // 简单进度条,意味者不显示文件名。
FOF_NOCONFIRMMKDIR = 0x0200, // 建新目录时不需要用户确定
FOF_NOERRORUI = 0x0400, // 不显示出错用户界面
FOF_NOCOPYSECURITYATTRIBS = 0x0800, // 不复制 NT 文件的安全属性
FOF_NORECURSION = 0x1000 // 不递归目录
}
public static bool Copy(string path, string dest, out string msg)
{
return Operation(WFUNC.FO_COPY, path, dest, out msg);
}
public static bool MoveTo(string path, string dest, out string msg)
{
return Operation(WFUNC.FO_MOVE, path, dest, out msg);
}
public static bool Delete(string path, out string msg)
{
return Operation(WFUNC.FO_DELETE, path, null, out msg);
}
public static bool Rename(string path, string dest, out string msg)
{
return Operation(WFUNC.FO_RENAME, path, dest, out msg);
}
private static bool Operation(WFUNC func, string path, string dest, out string msg)
{
SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT
{
wFunc = func,
pFrom = path + "\0",
fFlags = FILEOP_FLAGS.FOF_ALLOWUNDO,
fAnyOperationsAborted = false,
};
if (!string.IsNullOrEmpty(dest))
{
lpFileOp.pTo = dest + "\0";
}
int state = SHFileOperation(ref lpFileOp);
msg = GetAbortedString(state);
return state == 0;
}
private static string GetAbortedString(int code)
{
if (code == 0)
{
return "【操作完成】";
}
string state = code.ToString("X").ToUpper();
switch (state)
{
case "4C7":
return "【您已取消操作】";
//case "74":
// return "The source is a root directory, which cannot be moved or renamed.";
//case "76":
// return "Security settings denied access to the source.";
case "7C":
return "【路径错误】您操作路径的源或目标对象没有找到";
//case "10000":
// return "An unspecified error occurred on the destination.";
//case "402":
// return "An unknown error occurred. This is typically due to an invalid path " + "in the source or destination. This error does not occur on Windows Vista and later.";
default:
return state;
}
}
}
}
bool isSuccess = FileOperationManager.Copy(@"C:\1.txt", @"D:\2.txt", out string msg);
//isSuccess == True 成功
//msg 操作结果提示,自己继续完善下
MessageBox.Show(msg);