Windows 7 Forums

Welcome to Windows 7 Forums. Our forum is dedicated to helping you find support and solutions for any problems regarding your Windows 7 PC be it Dell, HP, Acer, Asus or a custom build. We also provide an extensive Windows 7 tutorial section that covers a wide range of tips and tricks.


Windows 7: Any way to reference the current drive, even if its letter changes?

05 Dec 2015   #11
pluviosilla

TX
 
 

Quote:
This is not a shorthand. The link will be created specifically with a relative path, exactly as it is specified in the command line (`\test` in this case)
That's good news. Do you know a way to edit a symbolic link and make it relative?

The folder structure on the disks I use are pretty deep and complex, and it is not practical to type lengthy paths in the cmd tool. It would be easier to create them using Windows Explorer enhanced with the Link Shell Extension then modify the links afterwords in the cmd tool to have the relative path.

Is that possible?


My System SpecsSystem Spec
.
06 Dec 2015   #12
Pyprohly

Windows 10, Windows 8.1 Pro, Windows 7 Professional, OS X El Capitan
 
 

AndreyT's solution works perfectly, Pluviosilla, and your claim below is incorrect.
Quote   Quote: Originally Posted by pluviosilla View Post
mklink /d testlink \test

works just fine. But your use of the "\" without the drive letter is little more than a shorthand for running the command [mklink /d testlink C:\test].
The given command is not a shorthand for any thing, and the two commands are indeed different. The command,
Code:
mklink /d TestLink C:\Test
will create an absolute path-ed symbolic link to 'C:\Test', whereas the command,
Code:
mklink /d TestLink \Test
will create a relative path-ed symbolic link to the folder 'Test', starting from the root directory of the drive containing the new 'TestLink' symbolic link. This is exactly the command you are after, Pluviosilla. There appears to be only one misunderstanding preventing you from accepting this:
Quote   Quote: Originally Posted by pluviosilla View Post
After creating your link, look at its properties in Windows Explorer. You will notice that Windows has inserted the drive letter. Furthermore, unlike shortcuts, users are not allowed to edit the Target area of the link.
As AndreyT has already tried explain to you, what you are observing is just Windows Explorer evaluating the path of the item the symbolic link points to; and it is not an indication of the data stored in the reparse point's buffer, thus the reason why this field cannot be edited.


Quote   Quote: Originally Posted by bigmck View Post
My whole life has been symbolic.
That's relatively deep.
My System SpecsSystem Spec
06 Dec 2015   #13
pluviosilla

TX
 
 

Pyprohly, I totally concede AndreyT's point. He has schooled me in the way this works, and I am grateful. That's why I came to this forum!

But thanks for confirming his information, because I haven't had a chance to test it by moving a drive between computers.

Do you happen to know how to modify the target of an existing symbolic link?

I use *hundreds* of shortcuts buried deeply within complex folder structures. I'd love to create links in Windows Explorer (enhanced with the Link Extension) and then just modify them to use relative instead of absolute paths.

I'm glad to know that mklink does what I want (thanks again), but using the clunky cmd shell to manually create soft links with huge path names is not very practical.
My System SpecsSystem Spec
.

07 Dec 2015   #14
Pyprohly

Windows 10, Windows 8.1 Pro, Windows 7 Professional, OS X El Capitan
 
 

Quote   Quote: Originally Posted by pluviosilla View Post
Do you happen to know [of a way] to modify the target of an existing symbolic link?

I use *hundreds* of shortcuts buried deeply within complex folder structures. I'd love to create links in Windows Explorer (enhanced with the Link Extension) and then just modify them to use relative instead of absolute paths.
Automatically processing hundreds of symbolic links isn't going to be nearly as easy as editing hundreds of desktop.ini files to support relative paths.

I Googled thoroughly and carefully in search for a way to edit a symbolic link's properties using Windows' builtin scripts and even sought for a solution through Autoit, but disappointing, I wasn't able to find any simple way to edit the properties of a symbolic link anywhere. There seems to be very little support for soft links across the board.

I'm unable to tell you such a method for editing a symbolic link, Pluviosilla, however, what I can do for you is create a PowerShell script that, instead of editing the symbolic links, creates a new symbolic link that replaces the old link in place, with the new relative path.

(TL;DR: Had to borrow a bit of code for this. I managed to find a function that gets the target directory of a symbolic link. Unfortunately the path that this function returns is an evaluated path to the item which the symbolic link points to, rather than the actual data representing the target item. This shouldn't make much of a difference, only you don't get to see what the old targets of the processed symbolic links were in the script's output.)


th-387133.ps1
Code:
#requires -RunAsAdministrator
# Administrative privileges typically needed to create symbolic links

filter Test-SymLink {
	if (fsutil.exe reparsepoint query $_ | Select-String '^Tag value: Symbolic Link$') {return $_}
}

function Get-ReparsePointTaregetDirectory {
	# reference: http://techibee.com/powershell/read-target-folder-of-a-symlink-using-powershell/1916
	[CmdletBinding()]
	param(
		[string]$Path
	)
	$Definition = @'
	private const int FILE_SHARE_READ = 1;
	private const int FILE_SHARE_WRITE = 2;
	private const int CREATION_DISPOSITION_OPEN_EXISTING = 3;
	private const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
	[DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)]
	public static extern int GetFinalPathNameByHandle(IntPtr handle, [In, Out] StringBuilder path, int bufLen, int flags);
	[DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
	public static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess,
	int dwShareMode, IntPtr SecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);

	public static string GetSymbolicLinkTarget(System.IO.DirectoryInfo symlink)
	{
		SafeFileHandle directoryHandle = CreateFile(symlink.FullName, 0, 2, System.IntPtr.Zero, CREATION_DISPOSITION_OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, System.IntPtr.Zero);
		if(directoryHandle.IsInvalid)
		throw new Win32Exception(Marshal.GetLastWin32Error());
		StringBuilder path = new StringBuilder(512);
		int size = GetFinalPathNameByHandle(directoryHandle.DangerousGetHandle(), path, path.Capacity, 0);
		if (size<0) throw new Win32Exception(Marshal.GetLastWin32Error()); // The remarks section of GetFinalPathNameByHandle mentions the return being prefixed with "\\?\" // More information about "\\?\" here -> http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx
		if (path[0] == '\\' && path[1] == '\\' && path[2] == '?' && path[3] == '\\') return path.ToString().Substring(4);
		else
		return path.ToString();
	}
'@
	Add-Type -MemberDefinition $Definition -Name Win32 -NameSpace System -UsingNamespace System.Text,Microsoft.Win32.SafeHandles,System.ComponentModel

	[System.Win32]::GetSymbolicLinkTarget($Path)
}

function New-SymLink {
	# https://gallery.technet.microsoft.com/scriptcenter/New-SymLink-60d2531e
	<#
		.SYNOPSIS
			Creates a Symbolic link to a file or directory

		.DESCRIPTION
			Creates a Symbolic link to a file or directory as an alternative to mklink.exe

		.PARAMETER Path
			Name of the path that you will reference with a symbolic link.

		.PARAMETER SymName
			Name of the symbolic link to create. Can be a full path/unc or just the name.
			If only a name is given, the symbolic link will be created on the current directory that the
			function is being run on.

		.PARAMETER File
			Create a file symbolic link

		.PARAMETER Directory
			Create a directory symbolic link

		.NOTES
			Name: New-SymLink
			Author: Boe Prox
			Created: 15 Jul 2013


		.EXAMPLE
			New-SymLink -Path "C:\users\admin\downloads" -SymName "C:\users\admin\desktop\downloads" -Directory

			SymLink                          Target                   Type
			-------                          ------                   ----
			C:\Users\admin\Desktop\Downloads C:\Users\admin\Downloads Directory

			Description
			-----------
			Creates a symbolic link to downloads folder that resides on C:\users\admin\desktop.

		.EXAMPLE
			New-SymLink -Path "C:\users\admin\downloads\document.txt" -SymName "SomeDocument" -File

			SymLink                             Target                                Type
			-------                             ------                                ----
			C:\users\admin\desktop\SomeDocument C:\users\admin\downloads\document.txt File

			Description
			-----------
			Creates a symbolic link to document.txt file under the current directory called SomeDocument.
	#>
	[cmdletbinding(
		DefaultParameterSetName = 'Directory',
		SupportsShouldProcess=$True
	)]
	Param (
		[parameter(Position=0,ParameterSetName='Directory',ValueFromPipeline=$True,
			ValueFromPipelineByPropertyName=$True,Mandatory=$True)]
		[parameter(Position=0,ParameterSetName='File',ValueFromPipeline=$True,
			ValueFromPipelineByPropertyName=$True,Mandatory=$True)]
		[ValidateScript({
			If (Test-Path $_) {$True} Else {
				Throw "`'$_`' doesn't exist!"
			}
		})]
		[string]$Path,
		[parameter(Position=1,ParameterSetName='Directory')]
		[parameter(Position=1,ParameterSetName='File')]
		[string]$SymName,
		[parameter(Position=2,ParameterSetName='File')]
		[switch]$File,
		[parameter(Position=2,ParameterSetName='Directory')]
		[switch]$Directory
	)
	Begin {
		Try {
			$null = [mklink.symlink]
		} Catch {
			Add-Type @"
			using System;
			using System.Runtime.InteropServices;
 
			namespace mklink
			{
				public class symlink
				{
					[DllImport("kernel32.dll")]
					public static extern bool CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);
				}
			}
"@
		}
	}
	Process {
		#Assume target Symlink is on current directory if not giving full path or UNC
		If ($SymName -notmatch "^(?:[a-z]:\\)|(?:\\\\\w+\\[a-z]\$)") {
			$SymName = "{0}\{1}" -f $pwd,$SymName
		}
		$Flag = @{
			File = 0
			Directory = 1
		}
		If ($PScmdlet.ShouldProcess($Path,'Create Symbolic Link')) {
			Try {
				$return = [mklink.symlink]::CreateSymbolicLink($SymName,$Path,$Flag[$PScmdlet.ParameterSetName])
				If ($return) {
					$object = New-Object PSObject -Property @{
						SymLink = $SymName
						Target = $Path
						Type = $PScmdlet.ParameterSetName
					}
					$object.pstypenames.insert(0,'System.File.SymbolicLink')
					$object
				} Else {
					Throw "Unable to create symbolic link!"
				}
			} Catch {
				Write-warning ("{0}: {1}" -f $path,$_.Exception.Message)
			}
		}
	}
}

Get-ChildItem | Test-SymLink | 
	%{
		$target = Get-ReparsePointTaregetDirectory $_.FullName
		[System.IO.Directory]::Delete($_.FullName)
		if ($?) {New-SymLink -Path ($target -replace '^.:') -SymName $_.FullName -Directory | select `
			@{n='Symlink Location';e={$_.SymLink}}, @{n='New Target';e={$_.Target}}
		}
	}
To begin, open an Elevated PowerShell session, change the current directory to that of your given starting directory by typing a line similar to,
Code:
cd 'C:\some\start\location'
then run the script by entering something like,
Code:
& 'C:\Users\Pyprohly\Downloads\script.ps1'
My System SpecsSystem Spec
07 Dec 2015   #15
pluviosilla

TX
 
 
Thanks!

My gosh. It's very kind of you to go to this kind of trouble. I'm very appreciative. I will study your script and try to use it.

I suspected that there might be a Power Shell solution out there somewhere.
My System SpecsSystem Spec
Reply

 Any way to reference the current drive, even if its letter changes?




Thread Tools Search this Thread
Search this Thread:

Advanced Search




Similar help and support threads
Thread Forum
modifying drive letter: Letter to choose not in the list
Hello I had to open my pc and remove drives. Once re-installed, one of the drive has seen it's letter allocation modified. Since 2 application is pointing to G drive, I would like to be able to get it back. Hard disk (2) Was G: Now, show has a D: CD drive was D: Now show has E: G:...
Hardware & Devices
changing one drive letter all 3 partitions change to that drive letter
sir, i have windows 7 desktop. there are some partition on it.but there is problem with these partition. All the three partition have the same drive letter.i attach a link showing the picture. all three partitions are dynamic , simple. if i open these drives only the contents of one drive are...
Hardware & Devices
How do you reset (clear) all current USB drive letter assignments?
How do you reset (clear) all current USB drive letter assignments? As a result of changing my external USB Hub controller from a CyberPower CP-H720P (USB 2.0 7-Port Hub w/Power Adapter) to a SIIG 06-0960A (USB 3.0 w/3-Ports & USB 2.0 w/3-Ports plus Card Reader w/Power Adapter), all of my...
Hardware & Devices
External Hard Drive - Drive Letter changed - unable to change back
I have a USB external hard drive that I keep all my documents etc on (had it for years) I upgraded from Vista Home to & Home Premium then had to upgrade recently to Professional to run my Sage. Through all these upgrades my ext. drive ran fine. Occasionally the drvie letter would change if I...
Hardware & Devices
Want to Assign a drive letter to a partitioned device but the letter i
Want to Assign a drive letter to a partitioned device but the letter is not in the list I created a partitioned drive I went to assign letter G but I don't see it in the list. no drive is using the letter G I do believe that some USB is using letter G, but I don't see my USBs ( see image) ...
General Discussion
Can't change hard drive letter to needed letter
I lost my Event Viewer, and had to do a repair installation to fix it. Unfortunately, during the repair install, Windows decided to rename my second HD as the D: drive... it was K: before that. Now I cannot access any of my docs, pictures, music, or videos through the normal means... they don't...
General Discussion


Our Sites

Site Links

About Us

Find Us

Windows 7 Forums is an independent web site and has not been authorized, sponsored, or otherwise approved by Microsoft Corporation. "Windows 7" and related materials are trademarks of Microsoft Corp.

Designer Media Ltd

All times are GMT -5. The time now is 13:26.

Twitter Facebook Google+



Windows 7 Forums

Seven Forums Android App Seven Forums IOS App