Win10: Using symbolic links in the PATH variable - windows

Here's the deal. I want to use a symbolic link to the latest installed Java version and create a symbolic link. The PATH variable shall contain the symbolic link as entry. The link is not resolved, though. Why?
Example:
$> dir C:\Program\ Files\Java
C:\Program\ Files\Java\jdk-1.14.1\
C:\Program\ Files\Java\jdk-latest.lnk # link to jdk-1.14.1
$> echo %PATH%
#...
C:\Program\ Files\Java\jdk-latest\bin
$> java --version
The command "java" is either written wrong or couldn't be found.

New-Item cmdlet with -ItemType SymbolicLink can be used to create symbolic link to file or folder.
Suppose, you have 2 folders containing 2 different versions of nodejs
node-v14.18.0-win-x64
node-v14.20.0-win-x64
We need one symbolic link, say rel which will point to one of the nodejs folders.
Add C:\Program\Files\nodejs\rel to PATH environment variable
Point rel to node v14.18.0
New-Item -Type SymbolicLink -Path .\rel -Target .\node-v14.18.0-win-x64 -Force
Verify node version
PS C:\Users\pvaddepa> node -v
v14.18.0
Use -Force to update the symbolic link to point to node v14.20.0.
New-Item -Type SymbolicLink -Path .\rel -Target .\node-v14.20.0-win-x64 -Force
Verify the node version
PS C:\Users\pvaddepa> node -v
v14.20.0
See New-Item example .

Related

Windows : navigate into symlink

I created a symbolic link in windows and it's working fine :)
when I run:
Get-ChildItem myLink
I get:
d----- MyFolder
But when I run:
cd myLink
It shows error of null exception
I want to run a solution in this path
myLink\MyFolder\mySolution.sln
How can I run it?
Tnx.
I used
New-Item -Path $newFolder -ItemType SymbolicLink -Value $oldFolder -Force
Using mklink works fine:
mklink /d $newFolder $oldFolder

How to find if a file exists under current directory under Powershell?

The question seems pretty easy, the method I used below should work but it doesn't:
PS C:\Users\John.Smith\Downloads> rm .\uucode.ps1
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("uucode.ps1")
True
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists(".\uucode.ps1")
True
I deleted the file, but it still indicates the file exists. I figured out that it is looking for the file under my home directory (even when "." is specified):
PS C:\Users\John.Smith\Downloads> rm ..\uucode.ps1
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("uucode.ps1")
False
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists(".\uucode.ps1")
False
Is this a bug or something? The OS and Powershell version I am using are:
PS C:\Users\John.Smith\Downloads> (Get-WmiObject -class Win32_OperatingSystem).Caption
Microsoft Windows Server 2012 R2 Standard
PS C:\Users\John.Smith\Downloads> $psversiontable.psversion
Major Minor Build Revision
----- ----- ----- --------
5 1 14409 1005
One solution I can think of myself is to find the current directory using pwd, and check if the file supplied to me is if a relative path (not starting with \ or /), and join the current directory with the relative path, but I think there should be an easier way, can you help me?
Is this a bug or something?
No, this behavior is expected.
.NET methods that take relative paths as arguments will resolve them relative to the working directory of the calling process - and powershell.exe doesn't update its current working directory when you navigate between locations inside PowerShell itself:
PS C:\Users\John.Smith> [System.Environment]::CurrentDirectory
C:\Users\John.Smith
PS C:\Users\John.Smith> cd Downloads
PS C:\Users\John.Smith\Downloads> [System.Environment]::CurrentDirectory
C:\Users\John.Smith
You can solve it by only passing rooted file system paths:
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("$PWD\uucode.ps1")
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists('C:\Users\John.Smith\Downloads\uucode.ps1')
... or, preferably, just stick to PowerShell's provider cmdlets - when in a FileSystem location, Test-Path -PathType Leaf would be the equivalent of [File]::Exists():
PS C:\Users\John.Smith\Downloads> Test-Path .\uucode.ps1 -PathType Leaf # always correctly resolves path relative to $PWD
If you want PowerShell to always update the current working directory of the host application process, you could do so in the prompt function
$function:prompt = {
# Need to check that we're in the file system - can't set process directory to a registry path for example
if ($PWD.Provider.Name -eq 'FileSystem') {
[System.IO.Directory]::SetCurrentDirectory($PWD)
}
return "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
}

Powershell Remove Symbolic Link Windows

I am having issues when removing SymbolicLinks which I have created with New-Item:
New-Item -ItemType SymbolicLink -Path C:\SPI -Target "C:\Users\Chino\Dropbox (Reserve Membership)\"
I need to modify the link because it has the wrong -Target, which should be:
New-Item -ItemType SymbolicLink -Path C:\SPI -Target "C:\Users\Chino\Dropbox (Reserve Membership)\SPI"
How to remove that link and assign a new one? Alternatively, how to update the target path of the existing link?
Calling Delete() on the corresponding DirectoryInfo object should do the trick:
(Get-Item C:\SPI).Delete()
New-Item -ItemType SymbolicLink -Path C:\SPI -Target "C:\Users\Chino\Dropbox (Reserve Membership)\SPI"
If you want to change the target path of the existing symbolic link C:\SPI from "C:\Users\Chino\Dropbox (Reserve Membership)\" to "C:\Users\Chino\Dropbox (Reserve Membership)\SPI\" you do not need to delete the link beforehand. Simply including the -Force parameter to overwrite the link works for me in PowerShell 5.1 on Windows 10 Pro v1603:
New-Item -ItemType SymbolicLink -Path C:\SPI -Target "C:\Users\Chino\Dropbox (Reserve Membership)\SPI" -Force
No way to update the symbolic link as far as I know. Gotta use CMD to remove symbolic link and you could then re-create it using your powershell script. You would do it like this in powershell.
cmd /c "rmdir C:\SPI"

New-Item recursive registry keys

With PowerShell you can run a command like this
ni c:/foo/bar -type directory
and it will create foo and bar as necessary. However if you run
ni hklm:software/classes/firefoxhtml/shell/edit/command -type directory
all keys but the last must exist or an error will be generated. Can PowerShell generate the parent keys as needed?
I was just missing the -force parameter
New-Item hklm:software/classes/firefoxhtml/shell/edit/command -Force
Using -Force will also remove everything under the key if it already exists so a better option would be
if(!(Test-Path $path)){
New-Item $path -Force;
}

Recursive svn upgrade in local filesystem (Win32)

There is a need to recursively run svn upgrade in certain directory in filesystem, ignoring non-svn subdirectories:
C:\a>svn upgrade
C:\a\b>svn upgrade
<skip non-svn dir>
C:\a\b\c>svn upgrade
...
This means we need to run svn upgrade command in every folder that has .svn inside it. How this can be done in win32? Found for d in find . -name .svn -type d; do svn upgrade $d/..; done routine for posix OS.
svn upgrade needs to be run at the top level of each working copy - you don't want to recurse into a WC 3 levels deep and then run it there, as you'll hose the WC. Reason: SVN pre-1.7 had a .svn directory in each directory of the working copy, while 1.7+ uses a single .svn in the root of the WC.
So, your recursion has to guarantee that you'll touch the top levels first - then as you go deeper if you find a .svn directory, you know it's a separate WC and not a child of another.
Batch is dead, use PowerShell. Put this in a .ps1 file (or the PowerShell ISE) and run it:
function upgrade-svndirs {
param (
[string]$PathToUpgrade
)
$Dirs = get-childitem $PathToUpgrade|where-object{$_.PSIsContainer};
foreach ($dir in $dirs) {
$DirName = $dir.FullName;
$isWC = Get-ChildItem $DirName -Filter ".svn" -Force;
if ($isWC) {
svn upgrade "$DirName";
}
upgrade-svndirs -PathToUpgrade $DirName;
}
}
upgrade-svndirs C:\a;

Resources