Vista et les liens symboliques

Description

Source simple mettant en oeuvre une nouveauté apparu sous Vista (existant déjà dans le monde Unix), les liens symboliques.
Pour ceux qui découvre, un lien symbolique (Symbolic link ou Symlink) est un "lien" sur un fichier ou répertoire créé au niveau du système de fichier NTFS. C'est en quelque sorte un "alias".

Cette classe offre la possibilité de créér des liens symboliques sur des fichiers ou répertoires. Mais aussi de savoir si un chemin est un lien symbolique sur un fichier/répertoire, de répertorier l'ensemble des liens symboliques existants sur des fichiers/répertoires.

Source / Exemple :


namespace Vista.IO
{
    /// <summary>
    /// Classe fournissant un moyen de créer un lien symbolique sur un fichier ou un répertoire.
    /// </summary>
    /// <remarks>Requiert une élévation de privilège.</remarks>
    public static class Symlink
    {
        /// <summary>
        /// Créé un lien symbolique sur un fichier ou un répertoire.
        /// </summary>
        /// <param name="path">Chemin fichier ou répertoire.</param>
        /// <param name="pathName">Chemin du lien symbolique.</param>
        /// <returns><b>True</b> si réussi;<b>False</b> en cas d'échec.</returns>
        /// <remarks>Prise en charge non supporté sur ressource réseau.</remarks>
        public static bool CreateSymbolicLink(string path, string pathName)
        {
            try
            {
                bool bSuccess = false;

                if (string.IsNullOrEmpty(pathName))
                    throw new Exception("The symbolic link name is empty.");

                if (PathIsDirectory(path))
                {
                    if (Directory.Exists(path))
                        bSuccess = NativeMethods.CreateSymbolicLink(pathName, path, NativeMethods.SYMLINK_FLAG_DIRECTORY);
                }
                else
                {
                    if (File.Exists(path))
                        bSuccess = NativeMethods.CreateSymbolicLink(pathName, path, NativeMethods.SYMLINK_FLAG_FILE);
                }

                return bSuccess;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// Récupère les liens symboliques existants sur des fichiers.
        /// </summary>
        /// <param name="path">Chemin à parcourir.</param>
        /// <param name="search">Profondeur de recherche.</param>
        /// <returns></returns>
        public static IEnumerable<string> GetSymbolicLinkFiles(string path, SearchOption search)
        {
            List<string> listF = new List<string>();

            if (PathIsDirectory(path))
            {
                if (Directory.Exists(path))
                {
                    try
                    {
                        listF.AddRange(Directory.GetFiles(path, "*", search));
                    }
                    catch (Exception)
                    { }

                    foreach (string file in listF)
                    {
                        if (FileIsSymbolicLink(file))
                            yield return file;
                    }

                }
            }
        }

        /// <summary>
        /// Récupère les liens symboliques existants sur des répertoires.
        /// </summary>
        /// <param name="path">Chemin à parcourir.</param>
        /// <param name="search">Profondeur de recherche.</param>
        /// <returns></returns>
        public static IEnumerable<string> GetSymbolicLinkDirectories(string path, SearchOption search)
        {
            List<string> listD = new List<string>();

            if (PathIsDirectory(path))
            {
                if (Directory.Exists(path))
                {
                    try
                    {
                        listD.AddRange(Directory.GetDirectories(path, "*", search));
                    }
                    catch (Exception)
                    { }

                    foreach (string dir in listD)
                    {
                        if (DirectoryIsSymbolicLink(dir))
                            yield return dir;
                    }

                }
            }
        }

        /// <summary>
        /// Indique si un chemin est un répertoire.
        /// </summary>
        /// <param name="path">Chemin à tester.</param>
        /// <returns><b>True</b> si répertoire;<b>False</b> si fichier ou autre.</returns>
        private static bool PathIsDirectory(string path)
        {
            try
            {
                if (!File.Exists(path))
                {
                    return ((new FileInfo(path).Attributes & FileAttributes.Directory) == FileAttributes.Directory)
                        ? true : false;
                }
                else
                    return false;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// Indique si un chemin est un lien symbolique sur un fichier.
        /// </summary>
        /// <param name="path">Fichier à tester.</param>
        /// <returns><b>True</b> si oui;<b>False</b> si non.</returns>
        public static bool FileIsSymbolicLink(string path)
        {
            return ((new FileInfo(path).Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
                ? true : false;
        }

        /// <summary>
        /// Indique si un chemin est un lien symbolique sur un répertoire.
        /// </summary>
        /// <param name="path">Fichier à tester.</param>
        /// <returns><b>True</b> si oui;<b>False</b> si non.</returns>
        public static bool DirectoryIsSymbolicLink(string path)
        {
            return ((new DirectoryInfo(path).Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
                ? true : false;
        }
    }
}

Conclusion :


Bien évidement utilisable sous Vista uniquement et Windows 2008 Server.
La création de lien symbolique nécessite une élévation de privilège. En conséquence pour tester, désactiver temporairement l'UAC.

Bon dév ++

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.