using System;
using System.Runtime.InteropServices;
using System.IO;
namespace
LxFile
{
public
class
FileOperateProxy
{
#region 【内部类型定义】
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,
FOF_CONFIRMMOUSE = 0x0002,
FOF_SILENT = 0x0044,
FOF_RENAMEONCOLLISION = 0x0008,
FOF_NOCONFIRMATION = 0x10,
FOF_WANTMAPPINGHANDLE = 0x0020,
FOF_ALLOWUNDO = 0x40,
FOF_FILESONLY = 0x0080,
FOF_SIMPLEPROGRESS = 0x0100,
FOF_NOCONFIRMMKDIR = 0x0200,
FOF_NOERRORUI = 0x0400,
FOF_NOCOPYSECURITYATTRIBS = 0x0800,
FOF_NORECURSION = 0x1000
}
#endregion 【内部类型定义】
#region 【DllImport】
[DllImport(
"shell32.dll"
)]
private
static
extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);
#endregion 【DllImport】
#region 【删除文件操作】
public
static
int DeleteFile(string fileName, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg)
{
try
{
string fName = GetFullName(fileName);
return
ToDelete(fName, toRecycle, showDialog, showProgress, ref errorMsg);
}
catch
(Exception ex)
{
errorMsg = ex.Message;
return
-200;
}
}
public
static
int DeleteFiles(string[] fileNames, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg)
{
try
{
string fName =
""
;
foreach
(string str in fileNames)
{
fName += GetFullName(str) +
"\0"
;
}
return
ToDelete(fName, toRecycle, showDialog, showProgress, ref errorMsg);
}
catch
(Exception ex)
{
errorMsg = ex.Message;
return
-200;
}
}
#endregion 【删除文件操作】
#region 【移动文件操作】
public
static
int MoveFile(string sourceFileName, string destinationPath, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg)
{
try
{
string sfName = GetFullName(sourceFileName);
string dfName = GetFullName(destinationPath);
return
ToMoveOrCopy(wFunc.FO_MOVE, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg);
}
catch
(Exception ex)
{
errorMsg = ex.Message;
return
-200;
}
}
public
static
int MoveFiles(string[] sourceFileNames, string destinationPath, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg)
{
try
{
string sfName =
""
;
foreach
(string str in sourceFileNames)
{
sfName += GetFullName(str) +
"\0"
;
}
string dfName = GetFullName(destinationPath);
return
ToMoveOrCopy(wFunc.FO_MOVE, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg);
}
catch
(Exception ex)
{
errorMsg = ex.Message;
return
-200;
}
}
#endregion 【移动文件操作】
#region 【复制文件操作】
public
static
int CopyFile(string sourceFileName, string destinationFileName, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg)
{
try
{
string sfName = GetFullName(sourceFileName);
string dfName = GetFullName(destinationFileName);
return
ToMoveOrCopy(wFunc.FO_COPY, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg);
}
catch
(Exception ex)
{
errorMsg = ex.Message;
return
-200;
}
}
public
static
int CopyFiles(string[] sourceFileNames, string destinationPath, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg)
{
try
{
string sfName =
""
;
foreach
(string str in sourceFileNames)
{
sfName += GetFullName(str) +
"\0"
;
}
string dfName = GetFullName(destinationPath);
return
ToMoveOrCopy(wFunc.FO_COPY, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg);
}
catch
(Exception ex)
{
errorMsg = ex.Message;
return
-200;
}
}
#endregion 【复制文件操作】
#region 【重命名文件】
[Obsolete(
"建议使用 Microsoft.VisualBasic.FileSystem.ReName()方法"
)]
public
static
int ReNameFile(string sourceFileName, string destinationFileName, bool showDialog, ref string errorMsg)
{
try
{
SHFILEOPSTRUCT lpFileOp =
new
SHFILEOPSTRUCT();
lpFileOp.wFunc = wFunc.FO_RENAME;
lpFileOp.pFrom = GetFullName(sourceFileName) +
"\0\0"
;
lpFileOp.pTo = GetFullName(destinationFileName) +
"\0\0"
;
lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOERRORUI;
if
(!showDialog)
lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION;
lpFileOp.fAnyOperationsAborted = true;
int n = SHFileOperation(ref lpFileOp);
if
(n == 0)
return
0;
string tmp = GetErrorString(n);
errorMsg = string.Format(
"{0}({1})"
, tmp, sourceFileName);
return
n;
}
catch
(Exception ex)
{
errorMsg = ex.Message;
return
-200;
}
}
public
static
void ReNameFile(string filePath, string newFileName)
{
try
{
string extensName = Path.GetExtension(filePath);
string newName = newFileName + extensName;
Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(filePath, newName);
}
catch
(Exception ex)
{
throw
ex;
}
}
#endregion 【重命名文件】
private
static
int ToDelete(string fileName, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg)
{
SHFILEOPSTRUCT lpFileOp =
new
SHFILEOPSTRUCT();
lpFileOp.wFunc = wFunc.FO_DELETE;
lpFileOp.pFrom = fileName +
"\0"
;
lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOERRORUI;
if
(toRecycle)
lpFileOp.fFlags |= FILEOP_FLAGS.FOF_ALLOWUNDO;
if
(!showDialog)
lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION;
if
(!showProgress)
lpFileOp.fFlags |= FILEOP_FLAGS.FOF_SILENT;
lpFileOp.fAnyOperationsAborted = true;
int n = SHFileOperation(ref lpFileOp);
if
(n == 0)
return
0;
string tmp = GetErrorString(n);
if
((fileName.ToLower().EndsWith(
".av"
) && n.ToString(
"X"
) ==
"402"
))
return
0;
errorMsg = string.Format(
"{0}({1})"
, tmp, fileName);
return
n;
}
private
static
int ToMoveOrCopy(wFunc flag, string sourceFileName, string destinationFileName,
bool showDialog, bool showProgress, bool autoRename, ref string errorMsg)
{
SHFILEOPSTRUCT lpFileOp =
new
SHFILEOPSTRUCT();
lpFileOp.wFunc = flag;
lpFileOp.pFrom = sourceFileName +
"\0"
;
lpFileOp.pTo = destinationFileName +
"\0\0"
;
lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOERRORUI;
lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMMKDIR;
if
(!showDialog)
lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION;
if
(!showProgress)
lpFileOp.fFlags |= FILEOP_FLAGS.FOF_SILENT;
if
(autoRename)
lpFileOp.fFlags |= FILEOP_FLAGS.FOF_RENAMEONCOLLISION;
lpFileOp.fAnyOperationsAborted = true;
int n = SHFileOperation(ref lpFileOp);
if
(n == 0)
return
0;
string tmp = GetErrorString(n);
errorMsg = string.Format(
"{0}({1})"
, tmp, sourceFileName);
return
n;
}
private
static
string GetFullName(string fileName)
{
FileInfo fi =
new
FileInfo(fileName);
return
fi.FullName;
}
private
static
string GetErrorString(int n)
{
if
(n == 0)
return
string.
Empty
;
switch
(n)
{
case
2:
return
"系统找不到指定的文件。"
;
case
7:
return
"存储控制块被销毁。您是否选择的“取消”操作?"
;
case
113:
return
"文件已存在!"
;
case
115:
return
"重命名文件操作,原始文件和目标文件必须具有相同的路径名。不能使用相对路径。"
;
case
117:
return
"I/O控制错误"
;
case
123:
return
"指定了重复的文件名"
;
case
116:
return
"The source is a root directory, which cannot be moved or renamed."
;
case
118:
return
"Security settings denied access to the source."
;
case
124:
return
"The path in the source or destination or both was invalid."
;
case
65536:
return
"An unspecified error occurred on the destination."
;
case
1026:
return
"在试图移动或拷贝一个不存在的文件."
;
case
1223:
return
"操作被取消!"
;
default
:
return
"未识别的错误代码:"
+ n;
}
}
}
}