使用c#,如何在Windows Vista,7,2008中复制符号链接

时间:2010-11-03 18:10:56

标签: c# .net-3.5 symlink

使用c#,如何在Windows Vista中复制符号链接,7,2008。

当我使用File.Copy复制符号链接时,会复制其目标。

我希望模仿使用带有/ B选项的xcopy时获得的行为。

这可以使用.NET 3.5吗?

4 个答案:

答案 0 :(得分:4)

您可以使用Win32 CopyFileEx函数执行此操作。需要花费一些精力,但这里是整个CopyFileEx帮助程序类(C#3.0和.NET 3.5 Client Profile兼容并经过测试!)。您还可以将其重用于您拥有的任何其他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);   
  }  

答案 1 :(得分:1)

.NET框架中没有链接API(硬链接,软链接或符号链接)。

您必须使用Process.Start致电mklink.exe并创建所需的链接, 或者您正在寻找能够做这些事情的第三方图书馆。

答案 2 :(得分:1)

您可以使用pinvoke并致电CopyFileEx。请注意您正在寻找的COPY_FILE_COPY_SYMLINK

答案 3 :(得分:0)

我知道这是一个相当古老的线程,但我刚刚完成了一些支持它的 C 代码工作(是的,真的)。发帖是因为我找遍了这方面的资料,不好找。

遗憾的是,CopyFileExCOPY_FILE_SYMLINK 并不能解决问题。这只是在目标目录中使用正确的名称创建一个 0 大小的文件,但没有符号链接。另一篇旧文章包含一个您可以尝试实施的解决方案:How to copy directory symbolic link as a link to the target?

我确实认为 CopyFileEx 的问题是一个错误,在 Windows 10 中仍然存在。