【问题标题】:Using c#, how do I copy a symbolic link in Windows Vista,7,2008使用c#,如何在Windows Vista,7,2008中复制符号链接
【发布时间】:2011-05-04 15:52:16
【问题描述】:

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

当我使用 File.Copy 复制符号链接时,它的目标被复制。

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

这可以使用 .NET 3.5 实现吗?

【问题讨论】:

    标签: c# .net-3.5 symlink


    【解决方案1】:

    您可以使用 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);   
      }  
    

    【讨论】:

      【解决方案2】:

      .NET 框架中没有用于链接(硬链接、软链接或符号链接)的 API。

      您必须使用Process.Start 调用mklink.exe 并创建所需的链接, 或者您可以寻找能够执行此类操作的第三方库。

      【讨论】:

        【解决方案3】:

        您可以使用pinvoke 并致电CopyFileEx。请注意COPY_FILE_COPY_SYMLINK,这就是您要查找的内容。

        【讨论】:

          【解决方案4】:

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

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

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

          【讨论】:

            猜你喜欢
            • 2010-09-16
            • 2010-09-30
            • 1970-01-01
            • 2011-03-23
            • 2015-01-03
            • 2012-04-25
            • 2011-04-08
            • 2021-09-04
            • 1970-01-01
            相关资源
            最近更新 更多