Используя С#, как скопировать символическую ссылку в Windows Vista, 7, 2008 г.

Используя С#, как мне скопировать символическую ссылку в Windows Vista,7,2008.

Когда я использую File.Copy для копирования символической ссылки, ее цель копируется.

Я хочу имитировать поведение, которое получается при использовании xcopy с параметром /B.

Возможно ли это с помощью .NET 3.5?


person Matt    schedule 03.11.2010    source источник


Ответы (3)


Для этого можно использовать функцию 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);   
  }  
person Michael Goldshteyn    schedule 03.11.2010

В среде .NET нет API для ссылок (жестких, программных или символических ссылок).

Вы должны вызвать mklink.exe с помощью Process.Start и создать нужную ссылку. , или вы ищете стороннюю библиотеку, которая может делать такие вещи.

person codymanix    schedule 03.11.2010

Вы можете использовать pinvoke и вызвать CopyFileEx. Обратите внимание на COPY_FILE_COPY_SYMLINK, который вы ищете.

person Aaron McIver    schedule 03.11.2010