Ejemplo n.º 1
0
        /// <summary>
        /// Wrapper for extern method CreateSymbolicLink.  This handles some error cases and provides better information
        /// in error cases.
        /// </summary>
        /// <param name="symlinkPath">Path to the symbolic link you wish to create.</param>
        /// <param name="targetPath">Path to the file/directory that the symbolic link should be pointing to.</param>
        public static void CreateSymbolicLink(string symlinkPath, string targetPath)
        {
            // Pre-checks.
            if (!(new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)))
            {
                throw new UnauthorizedAccessException("Process must be run in elevated permissions in order to create symbolic link.");
            }
            else if (Directory.Exists(symlinkPath) || File.Exists(symlinkPath))
            {
                throw new IOException("Path Already Exists.  We cannot create a symbolic link here");
            }

            // Create the correct symbolic link.
            bool result;

            if (SHFILEOPSTRUCT.Exists(targetPath))
            {
                result = CreateSymbolicLink(symlinkPath, targetPath, NativeMethods.SymbolicLink.File);
            }
            else if (Directory.Exists(targetPath))
            {
                result = CreateSymbolicLink(symlinkPath, targetPath, NativeMethods.SymbolicLink.Directory);
            }
            else
            {
                throw new FileNotFoundException("Target File/Directory was not found.  Cannot make a symbolic link.");
            }

            // Validate that we created a symbolic link.
            // If we failed and the symlink doesn't exist throw an exception here.
            if (!result)
            {
                if (!Directory.Exists(symlinkPath) && !File.Exists(symlinkPath))
                {
                    throw new FileNotFoundException("Unable to find symbolic link after creation.");
                }
                else
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }
            }
        }