调用windows复制对话框复制文件
一:结果演示1). 复制演示2). 提示覆盖3). 不提示覆盖
二. C#源代码三. AutoIt 源代码四. 文件说明及下载
命令行调用windows复制对话框复制文件,C#版可能有些Bug报错, 请测试使用!
一:结果演示
1). 复制演示
2). 提示覆盖
3). 不提示覆盖
二. C#源代码
using System
;
using System
.Collections
.Generic
;
using System
.Linq
;
using System
.Text
;
using System
.Threading
.Tasks
;
using System
.IO
;
using System
.Runtime
.InteropServices
;
namespace CopyX
{
class Program
{
public enum FO_Func
: uint
{
FO_MOVE
= 0x0001,
FO_COPY
= 0x0002,
FO_DELETE
= 0x0003,
FO_RENAME
= 0x0004,
}
[StructLayout(LayoutKind
.Sequential
, CharSet
= CharSet
.Unicode
, Pack
= 2)]
struct SHFILEOPSTRUCT
{
public IntPtr hwnd
;
public FO_Func wFunc
;
[MarshalAs(UnmanagedType
.LPWStr
)]
public string pFrom
;
[MarshalAs(UnmanagedType
.LPWStr
)]
public string pTo
;
public ushort 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, Out
] ref SHFILEOPSTRUCT lpFileOp
);
static string usage
= "调用Windows自带的复制文件对话框来复制文件。\n" +
"\n CopyX [/Y] source destination\n\n" +
"\t/Y \t不提示直接覆盖目标文件。\n" +
"\tsource \t指定要复制的文件。\n" +
"\tdestination\t为新文件指定目录和/或文件名。";
static int Main(string[] args
)
{
bool bOverWrite
= false;
string srcPath
= null, dstPath
= null;
foreach (string arg
in args
)
{
if (arg
== "/y" || arg
== "/Y")
{
bOverWrite
= true;
}
else if (srcPath
== null)
{
srcPath
= arg
;
}
else if (dstPath
== null)
{
dstPath
= arg
;
}
}
if (args
.Contains("/?") || srcPath
== null || dstPath
== null)
{
Console
.WriteLine(usage
);
return -1;
}
if ((!File
.Exists(srcPath
)) && (!Directory
.Exists(srcPath
)))
{
Console
.WriteLine("复制失败, 源文件不存在!");
return -1;
}
SHFILEOPSTRUCT lpFileOp
= new SHFILEOPSTRUCT();
lpFileOp
.hwnd
= IntPtr
.Zero
;
lpFileOp
.wFunc
= FO_Func
.FO_COPY
;
lpFileOp
.pFrom
= srcPath
+ '\0';
lpFileOp
.pTo
= dstPath
+ '\0';
lpFileOp
.fFlags
= bOverWrite
? (ushort)(0x0010 | 0x0200) : (ushort)0x0100;
lpFileOp
.hNameMappings
= IntPtr
.Zero
;
lpFileOp
.fAnyOperationsAborted
= false;
int ret
= SHFileOperation(ref lpFileOp
);
switch (ret
)
{
case 0x00: return 0;
case 0x71: Console
.WriteLine("The source and destination files are the same file."); break;
case 0x72: Console
.WriteLine("Multiple file paths were specified in the source buffer, but only one destination file path."); break;
case 0x73: Console
.WriteLine("Rename operation was specified but the destination path is a different directory. Use the move operation instead."); break;
case 0x74: Console
.WriteLine("The source is a root directory, which cannot be moved or renamed."); break;
case 0x75: Console
.WriteLine("The operation was canceled by the user, or silently canceled if the appropriate flags were supplied to SHFileOperation."); break;
case 0x76: Console
.WriteLine("The destination is a subtree of the source."); break;
case 0x78: Console
.WriteLine("Security settings denied access to the source."); break;
case 0x79: Console
.WriteLine("The source or destination path exceeded or would exceed MAX_PATH."); break;
case 0x7A: Console
.WriteLine("The operation involved multiple destination paths, which can fail in the case of a move operation."); break;
case 0x7C: Console
.WriteLine("The path in the source or destination or both was invalid."); break;
case 0x7D: Console
.WriteLine("The source and destination have the same parent folder."); break;
case 0x7E: Console
.WriteLine("The destination path is an existing file."); break;
case 0x80: Console
.WriteLine("The destination path is an existing folder."); break;
case 0x81: Console
.WriteLine("The name of the file exceeds MAX_PATH."); break;
case 0x82: Console
.WriteLine("The destination is a read-only CD-ROM, possibly unformatted."); break;
case 0x83: Console
.WriteLine("The destination is a read-only DVD, possibly unformatted."); break;
case 0x84: Console
.WriteLine("The destination is a writable CD-ROM, possibly unformatted."); break;
case 0x85: Console
.WriteLine("The file involved in the operation is too large for the destination media or file system."); break;
case 0x86: Console
.WriteLine("The source is a read-only CD-ROM, possibly unformatted."); break;
case 0x87: Console
.WriteLine("The source is a read-only DVD, possibly unformatted."); break;
case 0x88: Console
.WriteLine("The source is a writable CD-ROM, possibly unformatted."); break;
case 0xB7: Console
.WriteLine("MAX_PATH was exceeded during the operation."); break;
case 0x402: Console
.WriteLine("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."); break;
default: Console
.WriteLine("复制失败, 未知错误代码【" + ret
+ "】,参考: https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shfileoperationa"); break;
}
return ret
;
}
}
}
三. AutoIt 源代码
#NoTrayIcon
#pragma compile
(FileDescription
, '简单调用Windows自带复制对话框复制文件或文件夹'
)
#pragma compile
(FileVersion
, 1.0.0.0)
#pragma compile
(ProductName
, Leo
)
#pragma compile
(ProductVersion
, 1.0.0.0)
#pragma compile
(LegalCopyright
, Copyright ©
2020)
#pragma compile
(x64
, false
)
#pragma compile
(UPX
, true
)
#pragma compile
(Compression
, 9)
#pragma compile
(Console
, true
)
#include
<APIShellExConstants.au3
>
#include
<WinAPIFiles.au3
>
#include
<WinAPIShellEx.au3
>
Global $bOverWrite
= False
, $bHelp
= False
Global $srcPath
= ''
, $dstPath
= ''
For $i
= 1 To $CmdLine[
0]
If $CmdLine[$i]
= '
/y'
Then
$bOverWrite
= True
ElseIf $CmdLine[$i]
= '
/?'
Then
$bHelp
= True
ElseIf $srcPath
= ''
Then
$srcPath
= $CmdLine[$i]
ElseIf $dstPath
= ''
Then
$dstPath
= $CmdLine[$i]
EndIf
Next
If $bHelp
Or $srcPath
= ''
Or $dstPath
= ''
Then
ConsoleWrite
("调用Windows自带的复制文件对话框来复制文件。"
& @CRLF
& @CRLF
& _
"CopyX [
/Y] source destination"
& @CRLF
& @CRLF
& @
TAB & _
"
/Y 不提示直接覆盖目标文件。"
& @CRLF
& @
TAB & _
"source 指定要复制的文件。"
& @CRLF
& @
TAB & _
"destination 为新文件指定目录和
/或文件名。"
& @CRLF
)
Exit -1
EndIf
If FileExists
($srcPath
) <> 1 Then
ConsoleWriteError
('复制失败
, 源文件不存在
Exit -1
EndIf
If $bOverWrite
Then
_WinAPI_ShellFileOperation
($srcPath
, $dstPath
, $FO_COPY
, BitOR
($FOF_NOCONFIRMATION
, $FOF_NOCONFIRMMKDIR
))
Global $ret
= @extended
Else
_WinAPI_ShellFileOperation
($srcPath
, $dstPath
, $FO_COPY
, $FOF_SIMPLEPROGRESS
)
Global $ret
= @extended
EndIf
If $ret
<> 0 Then
ConsoleWriteError
("复制失败
,错误代码
: " & $ret & " 参考
: https
://www.autoitscript.
com/autoit3
/docs
/libfunctions
/_WinAPI_ShellFileOperation.htm"
)
Exit $ret
Else
Exit 0
EndIf
四. 文件说明及下载
C#版编译为DoNet4.5,Win7需安装4.5框架 AutoIt版默认支持Win7 ~ Win10 比较稳定 可自行编译
https://download.csdn.net/download/LeoForBest/12565079