【发布时间】:2011-05-04 15:52:16
【问题描述】:
使用c#,如何在Windows Vista,7,2008中复制符号链接。
当我使用 File.Copy 复制符号链接时,它的目标被复制。
我希望模仿使用带有 /B 选项的 xcopy 时的行为。
这可以使用 .NET 3.5 实现吗?
【问题讨论】:
使用c#,如何在Windows Vista,7,2008中复制符号链接。
当我使用 File.Copy 复制符号链接时,它的目标被复制。
我希望模仿使用带有 /B 选项的 xcopy 时的行为。
这可以使用 .NET 3.5 实现吗?
【问题讨论】:
您可以使用 Win32 CopyFileEx 函数来执行此操作。这需要一些努力,但这里是整个 CopyFileEx 助手类(C# 3.0 和 .NET 3.5 客户端配置文件兼容并经过测试!)。您还可以将它重用于您拥有的任何其他 CopyFileEx 任务:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
public static class CopyHelper
{
[Flags]
public enum CopyFileFlags : uint
{
COPY_FILE_FAIL_IF_EXISTS = 0x00000001,
COPY_FILE_RESTARTABLE = 0x00000002,
COPY_FILE_OPEN_SOURCE_FOR_WRITE = 0x00000004,
COPY_FILE_ALLOW_DECRYPTED_DESTINATION = 0x00000008,
COPY_FILE_COPY_SYMLINK = 0x00000800 //NT 6.0+
}
public enum CopyProgressResult : uint
{
PROGRESS_CONTINUE = 0,
PROGRESS_CANCEL = 1,
PROGRESS_STOP = 2,
PROGRESS_QUIET = 3
}
public enum CopyProgressCallbackReason : uint
{
CALLBACK_CHUNK_FINISHED = 0x00000000,
CALLBACK_STREAM_SWITCH = 0x00000001
}
public delegate CopyProgressResult CopyProgressRoutine(
long TotalFileSize,
long TotalBytesTransferred,
long StreamSize,
long StreamBytesTransferred,
uint dwStreamNumber,
CopyProgressCallbackReason dwCallbackReason,
IntPtr hSourceFile,
IntPtr hDestinationFile,
IntPtr lpData);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CopyFileEx(string lpExistingFileName,
string lpNewFileName, CopyProgressRoutine lpProgressRoutine,
IntPtr lpData, ref bool pbCancel, CopyFileFlags dwCopyFlags);
}
这里是一些示例代码,展示了如何使用它来复制符号链接(而不是它所引用的文件):
string srcLink = @"c:\l.txt"; // Sample source soft link
string destFile = @"d:\l.txt"; // Sample destination soft link
bool bCancel = false;
bool bSuccess = CopyHelper.CopyFileEx(srcLink, destFile,
null, IntPtr.Zero, ref bCancel,
CopyHelper.CopyFileFlags.COPY_FILE_COPY_SYMLINK);
if (!bSuccess)
{
int error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
【讨论】:
.NET 框架中没有用于链接(硬链接、软链接或符号链接)的 API。
您必须使用Process.Start 调用mklink.exe 并创建所需的链接,
或者您可以寻找能够执行此类操作的第三方库。
【讨论】:
您可以使用pinvoke 并致电CopyFileEx。请注意COPY_FILE_COPY_SYMLINK,这就是您要查找的内容。
【讨论】:
我知道这是一个相当古老的线程,但我刚刚完成了一些支持该线程的 C 代码(是的,真的)工作。发帖是因为我找遍了这方面的资料,好不容易找到。
遗憾的是,CopyFileEx 和 COPY_FILE_SYMLINK 并不能解决问题。这只是在目标目录中创建一个具有正确名称但没有符号链接的 0 大小文件。另一篇旧文章包含一个您可以尝试实施的解决方案:How to copy directory symbolic link as a link to the target?。
我确实认为CopyFileEx 的问题是一个错误,它仍然存在于 Windows 10 中。
【讨论】: