Feedback

Symbolischen Link erstellen, löschen und auslesen

/// <summary>
/// Stellt Funktionen zum erstellen, löschen und auslesen von symbolischen Links bereit.
/// </summary>
public static class SymbolicLink
{
    #region WinAPI

    [DllImport("kernel32.dll", EntryPoint = "CreateSymbolicLinkW", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool CreateSymbolicLink([In] string lpSymlinkFileName, [In] string lpTargetFileName, [In] int dwFlags);

    [DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern int GetFinalPathNameByHandle([In] IntPtr hFile, [Out] StringBuilder lpszFilePath, [In] int cchFilePath, [In] int dwFlags);

    [DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr SecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);

    private const int CREATION_DISPOSITION_OPEN_EXISTING = 3;
    private const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
    private const int SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1;

    #endregion

    /// <summary>
    /// Erstellt einen symbolischen Link.
    /// </summary>
    /// <param name="target">Das Ziel auf das der Link verweißen soll.</param>
    /// <param name="path">Der Pfad des symbolischen Links.</param>
    /// <param name="replaceExisting"><c>True</c>, wenn eine bereits existierende Datei bzw. ein bereits existierender symbolischer Link überschrieben werden soll.</param>
    public static void CreateSymbolicLink(string target, string path, bool replaceExisting)
    {
        if (replaceExisting) DeleteSymbolicLink(path);
        bool result = false;
        if (Directory.Exists(target))
        {
            result = CreateSymbolicLink(path, target, SYMBOLIC_LINK_FLAG_DIRECTORY);
        }
        else if (File.Exists(target))
        {
            result = CreateSymbolicLink(path, target, 0);
        }
        else
            throw new IOException("path not found");
        if (!result) throw new Win32Exception(Marshal.GetLastWin32Error());
    }

    /// <summary>
    /// Löscht einen symbolischen Link.
    /// </summary>
    /// <param name="path">Der Pfad zum symbolischen Link.</param>
    public static void DeleteSymbolicLink(string path)
    {
        if (Directory.Exists(path))
            Directory.Delete(path);
        if (File.Exists(path))
            File.Delete(path);
    }

    /// <summary>
    /// Gibt den Pfad eines Ordners oder einer Datei zurück wobei symbolische Links und bereit gestellte NTFS Ordner aufgelöst wurden.
    /// </summary>
    /// <param name="path">Der Pfad zu einem Ordner oder einer Datei.</param>
    /// <returns>Der wahre Pfad von <paramref name="path"/>.</returns>
    /// <remarks>Sollte kein Laufwerkpfad für den NTFS-Ordner verfügbar sein, so wird der Bereitstellungspfad zurück gegeben.</remarks>
    public static string GetRealPath(string path)
    {
        if (!Directory.Exists(path) && !File.Exists(path))
            throw new IOException("Path not found");

        DirectoryInfo symlink = new DirectoryInfo(path);//Es ist egel ob es eine Datei oder ein Ordner ist
        SafeFileHandle directoryHandle = CreateFile(symlink.FullName, 0, 2, System.IntPtr.Zero, CREATION_DISPOSITION_OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, System.IntPtr.Zero);//Handle zur Datei/Ordner
        if (directoryHandle.IsInvalid)
            throw new Win32Exception(Marshal.GetLastWin32Error());

        StringBuilder result = new StringBuilder(512);
        int mResult = GetFinalPathNameByHandle(directoryHandle.DangerousGetHandle(), result, result.Capacity, 0);
        if (mResult < 0)
            throw new Win32Exception(Marshal.GetLastWin32Error());
        if (result.Length >= 4 && result[0] == '\' && result[1] == '\' && result[2] == '?' && result[3] == '\')
            return result.ToString().Substring(4);// "\?" entfernen

1 Kommentar