[
  {
    "path": "README.md",
    "content": "# JC-jEnv\n\n> Author: JC0o0l,Jerrybird\n> \n> GitHub: https://github.com/chroblert/JC-jEnv.git\n> \n> WeChat: JC_SecNotes(Zer0ne安全研究)\n\n## 0x00 用途\nJava版本切换工具,可以很方便的在java的多个版本之间切换。可以设置只在当前的终端中生效还是在全局都生效。\n\n## 0x01 原理：\n\n- 通过reg,set,setx等命令修改或刷新JAVA_HOME,PATH,`<alias>`等环境变量以及注册表。\n\n- 将添加的`<alias>`保存到用户环境变量JC_jEnv中\n\n- 通过call来达到多重嵌套的效果\n\n- 通过doskey来设置命令别名\n\n## 0x02 效果：\n\n`jenv -h`\n\n![1611209361297.png](img/1611209361297.png)\n\n`jenv local java9`\n\n![1611210131816.png](img/1611210131816.png)\n\n`jenv version`\n\n![1611210177545.png](img/1611210177545.png)\n\n`jenv del java9`\n\n![1611210266710.png](img/1611210266710.png)\n\n`jenv add d:\\11-java\\jdk-9.0.4 java9`\n\n![1611210250119.png](img/1611210250119.png)\n\n\n\n\n## 0x03 参数说明：\n\n`jenv [options]`\n\noptions如下\n- version \n  - 显示当前设置的所有的java版本\n- local `<alias>` \n   - 设置java版本，只在当前shell下起作用\n- global `<alias>`\n   - 设置java版本，在全局下都起作用\n- add <目录> `<alias>`\n   - 添加一个版本的java。\n   - 如：`jenv add d:\\java\\jdk-9.0.4 java9`\n- del `<alias>`   \n   - 删除一个版本的java\n   - 如：`jenv del java9`\n\n## 0x04 使用说明：\n\n1. 将该bat脚本添加到PATH系统环境变量中\n\n    这样使用的时候，可以直接输入`jenv`\n2. 用户环境变量PATH中使用%JAVA_HOME%\\bin\n    \n    path环境变量中不能有具体的java路径，要使用%JAVA_HOME%\\bin的方式,无论系统环境变量还是用户环境变量\n\n3. 删除系统环境变量中的JAVA_HOME\n   因为生成path环境变量的时候，系统变量中的path>用户环境变量中的path。而要修改系统环境变量，需要管理员权限，所以该程序只修改了用户环境变量。\n\n注：\n> - 系统环境变量中PATH值中的路径下不能有java.exe。如：C:\\windows\\system32路径下有8版本的java.exe，则全局无法生效，即：即使jenv global java13,但每次新创建的cmd下运行的java都是C:\\windows\\system32路径下的那个。\n> - 该脚本使用用户环境变量，因而系统环境变量中不能有JAVA_HOME变量\n\n## 0x05 测试环境\n\n|序号|系统|版本|是否支持|\n|---|-|--|--------|\n|1|Windows 10|专业版|支持|\n|2|  |  |  |\n|3|  |  |  |\n|4|  |  |  |\n\n\n##  参考资料：\n\n参考资料：[windows系统一键配置修改环境变量](https://www.jianshu.com/p/7d90042f644f)\n\n参考资料：[Windows设置cmd别名](https://blog.csdn.net/YiRanZhiLiPoSui/article/details/83116819)\n\n参考资料：[setx设置永久环境变量](https://blog.csdn.net/fm0517/article/details/52450940)\n\n参考资料：[刷新环境变量](https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/redirects/RefreshEnv.cmd)\n\n参考资料：[batch之变量延迟](https://www.cnblogs.com/ini_always/archive/2012/02/16/2355031.html)\n\n参考资料：[was unexpect at this time](https://stackoom.com/question/2pffV/%E8%9D%99%E8%9D%A0-Set%E5%91%BD%E4%BB%A4%E5%9C%A8%E6%8B%AC%E5%8F%B7%E5%86%85%E4%B8%8D%E8%B5%B7%E4%BD%9C%E7%94%A8)\n\n参考资料：[批处理变量多重嵌套](https://www.cnblogs.com/xxcanghai/p/4584042.html)\n\n参考资料：[环境变量中特殊字符()的问题](https://qastack.cn/superuser/119610/spaces-and-parenthesis-in-windows-path-variable-screws-up-batch-files)\n\n参考资料：[setx1024个字符限制的解决方法](https://qastack.cn/superuser/387619/overcoming-the-1024-character-limit-with-setx)"
  },
  {
    "path": "jEnv.bat",
    "content": "@echo off\nchcp 65001\n@REM AUTHOR: JC0o0l,Jerrybird\n@REM description: java环境切换管理工具\n@REM Repo: https://github.com/Chroblert/JC-jEnv.git\n\n@REM set JC_jEnv=JC_jEnv\n\nif \"%1\" == \"local\" (\n    echo |set /p JCOut=\" [+] jenv local alias\"\n    echo.\n    goto switch_local \n)\n\nif \"%1\" == \"global\" (\n    echo | set /p JCOut=\" [+] jenv global alias\"\n    echo.\n    goto switch_global \n)\n\nif \"%1\" == \"add\" (\n    echo | set /p JCOut=\" [+] jenv add jdk_dir alias\"\n    echo.\n    goto addjdk\n)\nif \"%1\" == \"del\" (\n    echo | set /p JCOut=\" [+] jenv del alias\"\n    echo.\n    goto deljdk\n)\n\nif \"%1\" == \"version\" (\n    goto version\n)\n\n:usage\n    @REM echo | set /p JCOut=\" ================================================\"\n    echo ================================================\n    @REM echo.\n    echo | set /p JCOut=\" | JC-jEnv\"\n    echo.\n    echo | set /p JCOut=\" | Despt:  windows Java环境管理工具\"\n    echo.\n    echo | set /p JCOut=\" | Author: JC0o0l,Jerrybird\"\n    echo.\n    echo | set /p JCOut=\" | Repo:   https://github.com/chroblert/JC-jEnv.git\"\n    echo.\n    @REM echo | set /p JCOut=\" ================================================\"\n    echo ================================================\n    echo.\n    echo | set /p JCOut=\" 使用说明\"\n    echo.\n    echo | set /p JCOut=\"  jenv [options]\"\n    echo.\n    echo | set /p JCOut=\"       version \"\n    echo.\n    echo | set /p JCOut=\"         - 显示当前所有的java版本\"\n    echo.\n    echo | set /p JCOut=\"       local alias \"\n    echo.\n    echo | set /p JCOut=\"         - 设置java版本，只在当前shell下起作用\"\n    echo.\n    echo | set /p JCOut=\"       global alias \"\n    echo.\n    echo | set /p JCOut=\"         - 设置java版本，在全局下都起作用\"\n    echo.\n    echo | set /p JCOut=\"       add 目录 alias\"\n    echo.\n    echo | set /p JCOut=\"         - add a version \"\n    echo.\n    echo | set /p JCOut=\"       del alias     \"\n    echo.\n    echo | set /p JCOut=\"         - delete a version\"\n    echo.\n    goto end\n\n:version\n    if \"%JC_jEnv%\" == \"\" (\n        echo | set /p JCOut=\" 当前没有设置任何版本\"\n        echo.\n        goto usage\n    )\n    @REM 枚举JC_jEnv环境变量中的值\n    echo.\n    echo | set /p JCOut=\" all version:\"\n    echo.\n    set remain=%JC_jEnv%\n    setlocal enabledelayedexpansion\n:loop\n    for /f \"delims=;, tokens=1*\" %%i in (\"%remain%\") do (\n        @REM echo | set /p JCOut=\" %%i\"\n        @REM echo.\n        set jenv_name=%%i\n        set value=!%%i!\n        if /i \"!value!\" equ \"%JAVA_HOME%\" (\n            echo | set /p JCOut=\" * !jenv_name! !value!\"\n            echo.\n        ) else (\n            echo | set /p JCOut=\"   !jenv_name! !value!\"\n            echo.\n        )\n        set remain=%%j\n    )\n    if defined remain goto :loop\n    setlocal disabledelayedexpansion\n    goto end\n@REM 导出配置到文件\n:export\n    goto end\n\n@REM 导入配置文件\n:import\n    goto end\n:switch_local\n    @REM call refreshenv\n    set Java_env=%2\n    @REM 多重变量嵌套\n    call set TMP_JAVAHOME=%%%Java_env%%%\n    set java_path=\n    if NOT \"%2\" == \"\" (\n        set java_path=%TMP_JAVAHOME%\\bin\n    ) \n    if \"%java_path%\" == \"\" (\n        @REM 将(,)转义为^(,^)\n        goto end\n    )\n    set \"path=%java_path%;%path%\"\n    set \"JAVA_HOME=%TMP_JAVAHOME%\"\n    echo | set /p JCOut=\"  已切换到%2 %java_path%\"\n    echo.\n    @REM rem 设置别名\n    %SystemRoot%\\system32\\doskey %2=%JAVA_HOME%\\bin\\java.exe $*   >null\n    set java_path=\n    set TMP_JAVAHOME=\n    goto end\n\n:switch_global\n    @REM call refreshenv\n    set Java_env=%2\n    @REM 多重变量嵌套\n    call set TMP_JAVAHOME=%%%Java_env%%%\n    set java_path=\n    if \"%2\" == \"\" (\n        goto end\n    ) \n    set java_path=%TMP_JAVAHOME%\\bin\n    if \"%java_path%\" == \"\" (\n        goto end\n    )\n    REM 设置java_home环境变量\n    reg delete HKCU\\Environment /v JAVA_HOME /f >null\n    echo | set /p JCOut=\"  .使用reg删除以前的JAVA_HOME %JAVA_HOME%\"\n    echo.\n    reg add HKCU\\Environment  /v JAVA_HOME /t REG_SZ /d %TMP_JAVAHOME%  /f >null\n    echo | set /p JCOut=\"  .使用reg创建新的JAVA_HOME %TMP_JAVAHOME%\"\n    echo.\n    setx JAVA_HOME %TMP_JAVAHOME% >null\n    echo | set /p JCOut=\"  .使用setx更新JAVA_HOME\"\n    echo.\n    @REM 更新本shell中path\n    set \"path=%java_path%;%path%\"\n    set \"JAVA_HOME=%TMP_JAVAHOME%\"\n    @REM rem 设置别名\n    %SystemRoot%\\system32\\doskey %2=%JAVA_HOME%\\bin\\java.exe $*   >null\n    @REM echo | set /p JCOut=\" \"%path%\"\"\n    @REM echo.\n    set java_path=\n    set TMP_JAVAHOME=\n    goto end\n\n:setpathusereg\n    echo | set /p JCOut=\" 使用注册表设置PATH环境变量\"\n    echo.\n    echo | set /p JCOut=\" %~1   %~2\"\n    echo.\n    reg delete HKCU\\Environment /v %~1 /f\n    reg add HKCU\\Environment  /v %~1 /t REG_SZ /d \"%~2\"  /f\n    call refreshenv\n    goto :EOF\n    @REM reg add \"HKLM\\System\\CurrentControlSet\\Control\\Session Manager\\Environment\" /v JAVA_HOME /t REG_SZ /d \"%~1\" /f\n\n:deljdk\n    if NOT \"%~2\" == \"\" (\n        @REM 删除某个版本的jdk\n        reg delete HKCU\\Environment /v %~2 /f >null\n    )\n    call set t_JC_jEnv=%%JC_jEnv:;%~2=%%\n    call setx JC_jEnv %%t_JC_jEnv:%~2;=%%\n    call set JC_jEnv=%%t_JC_jEnv:%~2;=%%\n    set %~2=\n    goto refreshenv\n:addjdk\n    rem echo | set /p JCOut=\" [+] jenv add jdk_dir alias\"\n    rem echo.\n    if [%2] == [] (\n        echo | set /p JCOut=\" 请设置JDK路径\"\n        echo.\n        goto end\n    )\n    if [%3] == [] (\n        echo | set /p JCOut=\" 请设置JDK别名\"\n        echo.\n        goto end\n    )\n    if %2 == \"\" (\n        echo | set /p JCOut=\" 请设置JDK路径\"\n        echo.\n        goto end\n    )\n    if %3 == \"\" (\n        echo | set /p JCOut=\" 请设置JDK别名\"\n        echo.\n        goto end\n    )\n    set JDK_ALIAS=%3\n    set JDK_DIR=%2\n    @REM 判断是否存在JDK_ALIAS别名\n    call set t_temp=%%%JDK_ALIAS%%%\n    if NOT \"%t_temp%\" == \"\" (\n        echo | set /p JCOut=\" %JDK_ALIAS%已经存在\"\n        echo.\n        goto end\n    )\n    rem 添加至用户环境变量中\n    %SystemRoot%\\system32\\setx %JDK_ALIAS% %JDK_DIR% >null\n    @REM echo | set /p JCOut=\"/%SystemRoot%\\system32\\setx %JDK_ALIAS% %JDK_DIR% >>f:/JC_jEnv.cmd\"\n    @REM echo.\n    echo | set /p JCOut=\"%JC_jEnv%\"|%SystemRoot%\\system32\\findstr \"%JDK_ALIAS%\" >nul\n    echo.\n    set notexist=%errorlevel%\n    @REM 环境变量JC_jEnv中已存在当前要添加JAVA_ALIAS\n    if %notexist% == 0 (\n        echo | set /p JCOut=\" 已设置过该版本的java\"\n        echo.\n        goto end\n    )\n    @REM 保存添加的环境变量到JC_jEnv中\n    if \"%JC_jEnv%\" == \"\" (\n        echo | set /p JCOut=\" 用户环境变量中没有JC_jEnv\"\n        echo.\n        %SystemRoot%\\system32\\setx JC_jEnv \"%JDK_ALIAS%\" >null\n        @REM echo | set /p JCOut=\"/%SystemRoot%\\system32\\setx JC_jEnv \"%JDK_ALIAS%\" >>f:/JC_jEnv.cmd\"\n        @REM echo.\n    ) else (\n        %SystemRoot%\\system32\\setx JC_jEnv \"%JDK_ALIAS%;%JC_jEnv%\" >null\n        @REM echo | set /p JCOut=\"/%SystemRoot%\\system32\\setx JC_jEnv \"%JDK_ALIAS%;%JC_jEnv%\" >>f:/JC_jEnv.cmd\"\n        @REM echo.\n    )\n    @REM rem 设置别名\n    %SystemRoot%\\system32\\doskey %JDK_ALIAS%=%JDK_DIR%\\bin\\java.exe $*   >null\n    @REM echo | set /p JCOut=\"/%SystemRoot%\\system32\\doskey %JDK_ALIAS%=%JDK_DIR%\\bin\\java.exe $* >>f:/JC_jEnv.cmd\"\n    @REM echo.\n\n    echo | set /p JCOut=\" 已为%JDK_DIR%\\bin\\java.exe设置别名%JDK_ALIAS%\"\n    echo.\n    @REM 清空定义的变量\n    @REM set JDK_ALIAS=\n    set JDK_DIR=\n    @REM 刷新环境变量\n    goto refreshenv\n\n:refreshenv\n@echo off\n::\n:: RefreshEnv.cmd\n::\n:: Batch file to read environment variables from registry and\n:: set session variables to these values.\n::\n:: With this batch file, there should be no need to reload command\n:: environment every time you want environment changes to propagate\n\n::echo \"RefreshEnv.cmd only works from cmd.exe, please install the Chocolatey Profile to take advantage of refreshenv from PowerShell\"\necho | set /p dummy=\"Refreshing environment variables from registry for cmd.exe. Please wait...\"\n\ngoto main\n\n:: Set one environment variable from registry key\n:SetFromReg\n    \"%WinDir%\\System32\\Reg\" QUERY \"%~1\" /v \"%~2\" > \"%TEMP%\\_envset.tmp\" 2>NUL\n    for /f \"usebackq skip=2 tokens=2,*\" %%A IN (\"%TEMP%\\_envset.tmp\") do (\n        echo/set \"%~3=%%B\"\n    )\n    goto :EOF\n\n:: Get a list of environment variables from registry\n:GetRegEnv\n    \"%WinDir%\\System32\\Reg\" QUERY \"%~1\" > \"%TEMP%\\_envget.tmp\"\n    for /f \"usebackq skip=2\" %%A IN (\"%TEMP%\\_envget.tmp\") do (\n        if /I not \"%%~A\"==\"Path\" (\n            call :SetFromReg \"%~1\" \"%%~A\" \"%%~A\"\n        )\n    )\n    goto :EOF\n\n:main\n    echo/@echo off >\"%TEMP%\\_env.cmd\"\n\n    :: Slowly generating final file\n    call :GetRegEnv \"HKLM\\System\\CurrentControlSet\\Control\\Session Manager\\Environment\" >> \"%TEMP%\\_env.cmd\"\n    call :GetRegEnv \"HKCU\\Environment\">>\"%TEMP%\\_env.cmd\" >> \"%TEMP%\\_env.cmd\"\n\n    :: Special handling for PATH - mix both User and System\n    call :SetFromReg \"HKLM\\System\\CurrentControlSet\\Control\\Session Manager\\Environment\" Path Path_HKLM >> \"%TEMP%\\_env.cmd\"\n    call :SetFromReg \"HKCU\\Environment\" Path Path_HKCU >> \"%TEMP%\\_env.cmd\"\n\n    :: Caution: do not insert space-chars before >> redirection sign\n    echo/set \"Path=%%Path_HKLM%%;%%Path_HKCU%%\" >> \"%TEMP%\\_env.cmd\"\n\n    :: Cleanup\n    del /f /q \"%TEMP%\\_envset.tmp\" 2>nul\n    del /f /q \"%TEMP%\\_envget.tmp\" 2>nul\n\n    :: capture user / architecture\n    SET \"OriginalUserName=%USERNAME%\"\n    SET \"OriginalArchitecture=%PROCESSOR_ARCHITECTURE%\"\n\n    :: Set these variables\n    call \"%TEMP%\\_env.cmd\"\n\n    :: Cleanup\n    del /f /q \"%TEMP%\\_env.cmd\" 2>nul\n\n    :: reset user / architecture\n    SET \"USERNAME=%OriginalUserName%\"\n    SET \"PROCESSOR_ARCHITECTURE=%OriginalArchitecture%\"\n\n    echo | set /p dummy=\"Finished.\"\n    echo .\n    goto :EOF\n\n\n:end\n    echo.\n    echo Done\n"
  },
  {
    "path": "null",
    "content": ""
  }
]