C# VB FileSystem.Copy-如何获取重命名文件的新名称
我正在使用此函数将文件复制到程序目录:C# VB FileSystem.Copy-如何获取重命名文件的新名称,c#,.net,vb.net,filenames,C#,.net,Vb.net,Filenames,我正在使用此函数将文件复制到程序目录: new Computer().FileSystem.CopyFile(source, destination, UIOption.AllDialogs, UICancelOption.ThrowException); 如果存在具有相同名称的文件,
new Computer().FileSystem.CopyFile(source,
destination,
UIOption.AllDialogs,
UICancelOption.ThrowException);
如果存在具有相同名称的文件,则会向用户显示常规windows对话框,要求替换、取消或使用新名称复制
是否有返回该文件的新名称的方法?我找到了这个文件,它符合您的要求,但我的解释是C#
public class Win32ApiUtils
{
[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]
public struct SHFILEOPSTRUCT
{
public IntPtr hwnd;
public FO_Func WFunc;
[MarshalAs(UnmanagedType.LPWStr)]
public string PFrom;
[MarshalAs(UnmanagedType.LPWStr)]
public string pTO;
public ushort fFlags;
public bool FAnyOperationsAborted;
public IntPtr HNameMappings;
[MarshalAs(UnmanagedType.LPWStr)]
public string LpszProgressTitle;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct SHNAMEMAPPING
{
[MarshalAs(UnmanagedType.LPWStr)]
public string PszOldPath;
[MarshalAs(UnmanagedType.LPWStr)]
public string PszNewPath;
public int CchOldPath;
public int CchNewPath;
}
[StructLayout(LayoutKind.Sequential)]
private struct HANDLETOMAPPINGS
{
public uint UNumberOfMappings;
public IntPtr LpSHNameMapping;
}
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
private static extern int SHFileOperation(ref SHFILEOPSTRUCT LpFileOp);
[DllImport("Shell32.dll")]
private static extern void SHFreeNameMappings(SHNAMEMAPPING IntPtr);
public static int CopyFiles()
{
// set up our file operation structure
SHFILEOPSTRUCT sh;
sh.hwnd = IntPtr.Zero;
sh.WFunc = FO_Func.FO_COPY;
sh.PFrom = @"C:\temp\f1\a.txt" + Constants.vbNullChar + @"C:\temp\f1\b.txt" + Constants.vbNullChar +
Constants.vbNullChar;
sh.fFlags = (ushort)FILEOP_FLAGS_ENUM.FOF_ALLOWUNDO
| (ushort)FILEOP_FLAGS_ENUM.FOF_MULTIDESTFILES
| (ushort)FILEOP_FLAGS_ENUM.FOF_WANTMAPPINGHANDLE;
sh.FAnyOperationsAborted = false;
sh.HNameMappings = IntPtr.Zero;
sh.LpszProgressTitle = null;
sh.pTO = @"C:\temp\a.txt" + Constants.vbNullChar + @"C:\temp\b.txt" + Constants.vbNullChar +
Constants.vbNullChar;
int ret = SHFileOperation(ref sh);
if (sh.HNameMappings != IntPtr.Zero)
{
// Copy from Sh.HNameMappings to HANDLETOMAPPINGS
HANDLETOMAPPINGS mappings =
(HANDLETOMAPPINGS)Marshal.PtrToStructure(sh.HNameMappings, typeof(HANDLETOMAPPINGS));
// initialize the pointer for reading at the position of the mappings.LpSHNameMapping
IntPtr ptr = mappings.LpSHNameMapping;
for (int I = 0; I < (int)mappings.UNumberOfMappings; I++)
{
// read from the pointer
// copying to SHNAMEMAPPING
SHNAMEMAPPING mapping = (SHNAMEMAPPING)Marshal.PtrToStructure(ptr, typeof(SHNAMEMAPPING));
// create file info from mapping
// something we can get at
FileInfo fileNew = new FileInfo(mapping.PszNewPath);
Console.WriteLine("new file name: {0}", fileNew.Name);
// advance by the size of the structure to the next SHNAMEMAPPING
ptr = new IntPtr(ptr.ToInt32() + Marshal.SizeOf(typeof(SHNAMEMAPPING)));
}
}
return ret;
}
[Flags]
private enum FILEOP_FLAGS_ENUM : ushort
{
FOF_MULTIDESTFILES = 0x0001,
FOF_CONFIRMMOUSE = 0x0002,
FOF_SILENT = 0x0004, // don't create progress/report
FOF_RENAMEONCOLLISION = 0x0008,
FOF_NOCONFIRMATION = 0x0010, // Don't prompt the user.
FOF_WANTMAPPINGHANDLE = 0x0020, // Fill in SHFILEOPSTRUCT.hNameMappings
// Must be freed using SHFreeNameMappings
FOF_ALLOWUNDO = 0x0040,
FOF_FILESONLY = 0x0080, // on *.*, do only files
FOF_SIMPLEPROGRESS = 0x0100, // means don't show names of files
FOF_NOCONFIRMMKDIR = 0x0200, // don't confirm making any needed dirs
FOF_NOERRORUI = 0x0400, // don't put up error UI
FOF_NOCOPYSECURITYATTRIBS = 0x0800, // dont copy NT file Security Attributes
FOF_NORECURSION = 0x1000, // don't recurse into directories.
FOF_NO_CONNECTED_ELEMENTS = 0x2000, // don't operate on connected elements.
FOF_WANTNUKEWARNING = 0x4000,
// during delete operation, warn if nuking instead of recycling (partially overrides FOF_NOCONFIRMATION)
FOF_NORECURSEREPARSE = 0x8000, // treat reparse points as objects, not containers
}
public enum FO_Func : uint
{
FO_MOVE = 0x0001,
FO_COPY = 0x0002,
FO_DELETE = 0x0003,
FO_RENAME = 0x0004,
}
}
公共类win32aputils
{
[StructLayout(LayoutKind.Sequential,Pack=2,CharSet=CharSet.Unicode)]
公共结构SHFILEOPSTRUCT
{
公共IntPtr hwnd;
公共基金会;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串PFrom;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串pTO;
公众谘询文件;
公共图书馆的FanyoOperationsBorted;
公共IntPtr HNameMappings;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串名称;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
私有结构SHNAMEMAPPING
{
[Marshallas(UnmanagedType.LPWStr)]
公共字符串PszOldPath;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串PszNewPath;
公共路径;
公共int CchNewPath;
}
[StructLayout(LayoutKind.Sequential)]
私有结构HANDLETOMAPPINGS
{
公共uint UNOMBEROF映射;
公共IntPtr-LpSHNameMapping;
}
[DllImport(“Shell32.dll”,CharSet=CharSet.Unicode)]
私有静态外部int SHFileOperation(ref SHFILEOPSTRUCT LpFileOp);
[DllImport(“Shell32.dll”)]
私有静态外部void SHFreeNameMappings(SHNAMEMAPPING IntPtr);
公共静态int-CopyFiles()
{
//建立我们的文件操作结构
SHFILEOPSTRUCT-sh;
sh.hwnd=IntPtr.Zero;
sh.WFunc=FO_Func.FO_COPY;
sh.PFrom=@“C:\temp\f1\a.txt”+Constants.vbNullChar+@“C:\temp\f1\b.txt”+Constants.vbNullChar+
常量.vbNullChar;
sh.fFlags=(ushort)FILEOP_FLAGS_ENUM.FOF_ALLOWUNDO
|(ushort)FILEOP_FLAGS_ENUM.FOF_MULTIDESTFILES
|(ushort)FILEOP_FLAGS_ENUM.FOF_WANTMAPPINGHANDLE;
sh.fanyooperatisaborted=false;
sh.hnamappings=IntPtr.Zero;
sh.LpszProgressTitle=null;
sh.pTO=@“C:\temp\a.txt”+Constants.vbNullChar+@“C:\temp\b.txt”+Constants.vbNullChar+
常量.vbNullChar;
int-ret=SHFileOperation(ref-sh);
如果(sh.HNameMappings!=IntPtr.Zero)
{
//从Sh.HNameMappings复制到HANDLETOMAPPINGS
HANDLETOMAPPINGS映射=
(手册手册)结构(sh.HNameMappings,手册手册类型);
//初始化指针以在mappings.LpSHNameMapping的位置读取
IntPtr ptr=mappings.LpSHNameMapping;
对于(int I=0;I<(int)映射。UNumberOfMappings;I++)
{
//从指针读取
//复制到SHNAMEMAPPING
SHNAMEMAPPING=(SHNAMEMAPPING)Marshal.PtrToStructure(ptr,typeof(SHNAMEMAPPING));
//从映射创建文件信息
//我们能找到的东西
FileInfo fileNew=newfileinfo(mapping.PszNewPath);
WriteLine(“新文件名:{0}”,fileNew.name);
//按结构的大小前进到下一个SHNAMEMAPPING
ptr=newintptr(ptr.ToInt32()+Marshal.SizeOf(typeof(SHNAMEMAPPING));
}
}
返回ret;
}
[旗帜]
私有枚举文件op_标志_枚举:ushort
{
FOF_MULTIDESTFILES=0x0001,
FOF_CONFIRMMOUSE=0x0002,
FOF_SILENT=0x0004,//不创建进度/报告
FOF_重命名碰撞=0x0008,
FOF_NOCONFIRMATION=0x0010,//不提示用户。
FOF_WANTMAPPINGHANDLE=0x0020,//填写SHFILEOPSTRUCT.hnamAppings
//必须使用SHFreeNameMappings释放
FOF_ALLOWUNDO=0x0040,
FOF_FILESONLY=0x0080,//在**上,仅执行文件
FOF_SIMPLEPROGRESS=0x0100,//表示不显示文件名
FOF_noconfirmkdir=0x0200,//不确认生成任何所需的dir
FOF_NOERRORUI=0x0400,//不显示错误UI
FOF_NOCOPYSECURITYATTRIBS=0x0800,//不复制NT文件安全属性
FOF_NORECURSION=0x1000,//不要递归到目录中。
FOF_NO_CONNECTED_ELEMENTS=0x2000,//不要对连接的元素进行操作。
FOF_WANTNUKEWARNING=0x4000,
//在删除操作期间,如果使用nuking而不是recycling,则发出警告(部分覆盖FOF_NOCONFIRMATION)
FOF_norecurseresparse=0x8000,//将重分析点视为对象,而不是容器
}
公共枚举函数:uint
{
FO_MOVE=0x0001,
FO_COPY=0x0002,
FO_DELETE=0x0003,
FO_RENAME=0x0004,
}
}
}为什么不确认文件不存在?它们可能是两个同名的不同文件。我可以做所有的检查,并询问重命名或覆盖我自己,但这违背了使用此功能的目的function@mobiletim我认为,无论是使用此函数还是使用诸如SHCopyFile或其他相关API之类的Windows API函数,都无法得到您想要的结果,因为它们都是(至少是我知道的那些,只返回一个错误代码或布尔值,表明如果复制操作成功),您可能希望向用户询问并负责重命名和覆盖您自己。基础Windows API函数(SHFileOperation)能够通过SHFILEOPSTRUCT.hNameMappings成员返回此信息。您需要的pinvoke是Gratty。