当 Java 自动更新时更新 Windows 路径变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1690815/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:24:26  来源:igfitidea点击:

Update Windows path variable when Java is updated automatically?

javawindowspath-variables

提问by Mark Norgren

This questionasks how to setup your path variable in Windows to include the Java bin directory allowing you to use the javac command from the prompt. The solution posted to this question states you should hard code the absolute path of the latest Java installation.

此问题询问如何在 Windows 中设置路径变量以包含 Java bin 目录,从而允许您从提示符使用 javac 命令。发布到此问题的解决方案指出您应该对最新 Java 安装的绝对路径进行硬编码。

In this case it happens to be c:\program files\java\jdk1.6.0_16\bin

在这种情况下,它恰好是 c:\program files\java\jdk1.6.0_16\bin

I believe once Java update 17, 18 and beyond are installed your javac cmd will still be using this older version, correct?

我相信一旦安装了 Java 更新 17、18 及更高版本,您的 javac cmd 仍将使用这个旧版本,对吗?

Am I missing something?? Is there a way to set this to automatically use the most recent installed java update??

我错过了什么吗??有没有办法将其设置为自动使用最近安装的 Java 更新?

回答by OscarRyz

I believe once Java update 17, 18 and beyond are installed your javac cmd will still be using this older version, correct?

我相信一旦安装了 Java 更新 17、18 及更高版本,您的 javac cmd 仍将使用这个旧版本,对吗?

Correct. When java is update, what get's updated is the JRE ( java runtime environment )

正确的。java更新时,更新的是JRE(java运行时环境)

That automatically set your java plugin ( used in the browser ) and your java command set to the latest version. ( Open a terminal and type java -version )

这会自动将您的 java 插件(在浏览器中使用)和您的 java 命令设置为最新版本。(打开终端并输入 java -version )

The SDK ( Java SDK ) which contains the javac is notchanged. You have to do it manually.

包含 javac 的 SDK ( Java SDK )没有改变。你必须手动完成。

One option is do what mhaller says.

一种选择是按照 mhaller 所说的去做。

I go further using the environment variables in Windows.

我进一步使用 Windows 中的环境变量。

MyPC/RigthClick/Properties/Advaced/EnvironmentVariables/

MyPC/RigthClick/属性/高级/环境变量/

From there I add JAVA_HOME poiting to the desired JDK path ( c:\jsdk_x_x_x ) and set the PATH variable to:

从那里我将 JAVA_HOME 指向所需的 JDK 路径( c:\jsdk_x_x_x )并将 PATH 变量设置为:

 whatever;_it_had;_before;%JAVA_HOME%\bin

Is there a way to set this to automatically use the most recent installed java update??

有没有办法将其设置为自动使用最近安装的 Java 更新?

For the JRE it would be automatically set, for the SDK you'll only need to modify the system variables and change the value of JAVA_HOME

对于 JRE,它将自动设置,对于 SDK,您只需要修改系统变量并更改的值 JAVA_HOME

回答by mhaller

Use the variable set by the Java Installer instead:

改用 Java 安装程序设置的变量:

set path="%path%;%JAVA_HOME%\bin"

回答by Erwin Mayer

The following Powershell script works very well for this:

以下 Powershell 脚本非常适用于此:

Remove-PathFolders -Folders "*\Java\jdk*" -EnvironmentVariableTarget $([System.EnvironmentVariableTarget]::Machine)
$jdkDp = (Get-ChildItem -Path "C:\Program Files (x86)\Java\jdk*" | Sort-Object name | Select-Object -Last 1).FullName
Add-PathFolders -Folders $($jdkDp + "\bin\") -EnvironmentVariableTarget $([System.EnvironmentVariableTarget]::Machine)
Get-PathFolders -EnvironmentVariableTarget $([System.EnvironmentVariableTarget]::Machine)

Which use the following custom functions inspired from here(you can include everything in the same UpdateJavaPath.ps1script):

使用以下灵感来自此处的自定义函数(您可以在同一个UpdateJavaPath.ps1脚本中包含所有内容):

<#
.SYNOPSIS
Gets the list of folders specified in the Path environment variable.

.PARAMETER EnvironmentVariableTarget
Specifies the "scope" to use when querying the Path environment variable
("Process", "Machine", or "User"). Defaults to "Process" if the parameter is
not specified.

.EXAMPLE
.\Get-PathFolders.ps1
C:\Windows\system32\WindowsPowerShell\v1.0\
C:\Windows\system32
C:\Windows
C:\Windows\System32\Wbem
...

Description
-----------
The output from this example lists each folder in the Path environment variable
for the current process.

.EXAMPLE
.\Get-PathFolders.ps1 User
C:\NotBackedUp\Public\Toolbox

Description
-----------
The output from this example assumes one folder
("C:\NotBackedUp\Public\Toolbox") has previously been added to the user's Path
environment variable.
#>
Function Get-PathFolders() {
    param(
        [string] $EnvironmentVariableTarget = "Process")

    Set-StrictMode -Version Latest
    $ErrorActionPreference = "Stop"

    [string[]] $pathFolders = [Environment]::GetEnvironmentVariable(
        "Path",
        $EnvironmentVariableTarget) -Split ";"

    If ($pathFolders -ne $null)
    {
        Write-Output $pathFolders
    }
}

<#
.SYNOPSIS
Adds one or more folders to the Path environment variable.

.PARAMETER Folders
Specifies the folders to add to the Path environment variable..

.PARAMETER EnvironmentVariableTarget
Specifies the "scope" to use for the Path environment variable ("Process",
"Machine", or "User"). Defaults to "Process" if the parameter is not specified.

.EXAMPLE
.\Add-PathFolders.ps1 C:\NotBackedUp\Public\Toolbox
#>
Function Add-PathFolders() {
    param(
        [parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string[]] $Folders,
        [string] $EnvironmentVariableTarget = "Process")

    begin
    {
        Set-StrictMode -Version Latest
        $ErrorActionPreference = "Stop"

        Write-Verbose "Path environment variable target: $EnvironmentVariableTarget"

        [bool] $isInputFromPipeline =
            ($PSBoundParameters.ContainsKey("Folders") -eq $false)

        [int] $foldersAdded = 0

        [string[]] $pathFolders = [Environment]::GetEnvironmentVariable(
            "Path",
            $EnvironmentVariableTarget) -Split ";"

        [Collections.ArrayList] $folderList = New-Object Collections.ArrayList

        $pathFolders | foreach {
            $folderList.Add($_) | Out-Null
        }
    }

    process
    {
        If ($isInputFromPipeline -eq $true)
        {
            $items = $_
        }
        Else
        {
            $items = $Folders
        }

        $items | foreach {
            [string] $folder = $_

            [bool] $isFolderInList = $false

            $folderList | foreach {
                If ([string]::Compare($_, $folder, $true) -eq 0)
                {
                    Write-Verbose ("The folder ($folder) is already included" `
                        + " in the Path environment variable.")

                    $isFolderInList = $true
                    return
                }
            }

            If ($isFolderInList -eq $false)
            {
                Write-Verbose ("Adding folder ($folder) to Path environment" `
                    + " variable...")

                $folderList.Add($folder) | Out-Null

                $foldersAdded++
            }
        }
    }

    end
    {
        If ($foldersAdded -eq 0)
        {
            Write-Verbose ("No changes to the Path environment variable are" `
                + " necessary.")

            return
        }

        [string] $delimitedFolders = $folderList -Join ";"

        [Environment]::SetEnvironmentVariable(
            "Path",
            $delimitedFolders,
            $EnvironmentVariableTarget)

        Write-Verbose ("Successfully added $foldersAdded folder(s) to Path" `
            + " environment variable.")
    }
}

<#
.SYNOPSIS
Removes one or more folders from the Path environment variable.

.PARAMETER Folders
Specifies the folders to remove from the Path environment variable..

.PARAMETER EnvironmentVariableTarget
Specifies the "scope" to use for the Path environment variable ("Process",
"Machine", or "User"). Defaults to "Process" if the parameter is not specified.

.EXAMPLE
.\Remove-PathFolders.ps1 C:\NotBackedUp\Public\Toolbox
#>
Function Remove-PathFolders(){
    param(
        [parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string[]] $Folders,
        [string] $EnvironmentVariableTarget = "Process")

    begin
    {
        Set-StrictMode -Version Latest
        $ErrorActionPreference = "Stop"

        Write-Verbose "Path environment variable target: $EnvironmentVariableTarget"

        [bool] $isInputFromPipeline =
            ($PSBoundParameters.ContainsKey("Folders") -eq $false)

        [int] $foldersRemoved = 0

        [string[]] $pathFolders = [Environment]::GetEnvironmentVariable(
            "Path",
            $EnvironmentVariableTarget) -Split ";"

        [Collections.ArrayList] $folderList = New-Object Collections.ArrayList

        $pathFolders | foreach {
            $folderList.Add($_) | Out-Null
        }
    }

    process
    {
        If ($isInputFromPipeline -eq $true)
        {
            $items = $_
        }
        Else
        {
            $items = $Folders
        }

        $items | foreach {
            [string] $folder = $_

            [bool] $isFolderInList = $false

            for ([int] $i = 0; $i -lt $folderList.Count; $i++)
            {
                #If ([string]::Compare($folderList[$i], $folder, $true) -eq 0)
                if (($folderList[$i] -like $folder) -or ($folderList[$i] -eq ""))
                {
                    $isFolderInList = $true

                    Write-Verbose ("Removing folder ($folderList[$i]) from Path" `
                        + " environment variable...")

                    $folderList.RemoveAt($i)
                    $i--

                    $foldersRemoved++
                }
            }

            If ($isFolderInList -eq $false)
            {
                Write-Verbose ("The folder ($folder) is not specified in the Path" `
                    + " list.")

            }
        }
    }

    end
    {
        If ($foldersRemoved -eq 0)
        {
            Write-Verbose ("No changes to the Path environment variable are" `
                + " necessary.")

            return
        }

        [string] $delimitedFolders = $folderList -Join ";"

        [Environment]::SetEnvironmentVariable(
            "Path",
            $delimitedFolders,
            $EnvironmentVariableTarget)

        Write-Verbose ("Successfully removed $foldersRemoved folder(s) from Path" `
            + " environment variable.")
    }
}