/// <summary> /// Creates a junction point from the specified directory to the specified target directory. /// </summary> /// <remarks> /// Only works on NTFS. /// </remarks> /// <param name = "junctionPoint">The junction point path</param> /// <param name = "targetDir">The target directory</param> /// <param name = "overwrite">If true overwrites an existing reparse point or empty directory</param> /// <exception cref = "IOException">Thrown when the junction point could not be created or when /// an existing directory was found and <paramref name = "overwrite" /> if false</exception> public static void Create(Directory junctionPoint, string targetDir, bool overwrite) { //targetDir = Path.GetFullPath(targetDir); if (junctionPoint.Exists()) { if (!overwrite) throw new IOException("Directory already exists and overwrite parameter is false."); } else junctionPoint.Create(); using (var handle = OpenReparsePoint(junctionPoint.Path, EFileAccess.GenericWrite)) { var targetDirBytes = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + Path.GetFullPath(targetDir)); var reparseDataBuffer = new REPARSE_DATA_BUFFER(); reparseDataBuffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; reparseDataBuffer.ReparseDataLength = (ushort) (targetDirBytes.Length + 12); reparseDataBuffer.SubstituteNameOffset = 0; reparseDataBuffer.SubstituteNameLength = (ushort) targetDirBytes.Length; reparseDataBuffer.PrintNameOffset = (ushort) (targetDirBytes.Length + 2); reparseDataBuffer.PrintNameLength = 0; reparseDataBuffer.PathBuffer = new byte[0x3ff0]; Array.Copy(targetDirBytes, reparseDataBuffer.PathBuffer, targetDirBytes.Length); var inBufferSize = Marshal.SizeOf(reparseDataBuffer); var inBuffer = Marshal.AllocHGlobal(inBufferSize); try { Marshal.StructureToPtr(reparseDataBuffer, inBuffer, false); int bytesReturned; var result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_SET_REPARSE_POINT, inBuffer, targetDirBytes.Length + 20, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); if (!result) ThrowLastWin32Error("Unable to create junction point."); } finally { Marshal.FreeHGlobal(inBuffer); } } }