Repository: pyenv-win/pyenv-win (language: python)

Issue:
bug: pyenv exec broken with many versions
**Describe the bug**
pyenv exec python3.X -V does not work for all activated versions. Error:

> This file does not have an app associated with it for performing this action. [...]
> The system cannot execute the specified program.

**To Reproduce**
Steps to reproduce the behavior:
- [...]
- pyenv local 3.7.7 3.8.9
- pyenv exec python3.7 -V

**Expected behavior**
Show python version for all activated versions.

**Additional context**
Add any other context about the problem here.



Discussion / hints:

Fix patch:
diff --git a/.version b/.version
index 766639f6..f56d49a1 100644
--- a/.version
+++ b/.version
@@ -1,1 +1,1 @@
-2.64.7.2
\ No newline at end of file
+2.64.7.3
\ No newline at end of file
diff --git a/README.md b/README.md
index 9b67ec22..536d2bea 100644
--- a/README.md
+++ b/README.md
@@ -222,6 +222,9 @@ Now follow the steps to "[finish the installation](#finish-the-installation)".
 
 ## Change Log
 
+### New in 2.64.7.3
+- Fix [#254](https://github.com/pyenv-win/pyenv-win/issues/254): Fix exec with many local versions.
+
 ### New in 2.64.7.2
 - Fix [#250](https://github.com/pyenv-win/pyenv-win/issues/250): PATH is not impacted after a `pyenv exec`.
 
diff --git a/pyenv-win/bin/pyenv.bat b/pyenv-win/bin/pyenv.bat
index 3974dca1..7c6e0549 100644
--- a/pyenv-win/bin/pyenv.bat
+++ b/pyenv-win/bin/pyenv.bat
@@ -12,7 +12,8 @@ if [%1]==[] (
 
 :: use pyenv.vbs to aid resolving absolute path of "active" version into 'bindir'
 set "bindir="
-for /f %%i in ('%pyenv% vname') do call :normalizepath "%~dp0..\versions\%%i" bindir
+set "extrapaths="
+for /f %%i in ('%pyenv% vname') do call :extrapath "%~dp0..\versions\%%i"
 
 :: all help implemented as plugin
 if /i [%2]==[--help] goto :plugin
@@ -56,7 +57,7 @@ set cmdline=%cmdline:~5%
 set cmddir=
 if exist %bindir%\%2 set cmddir=%bindir%\
 if exist %bindir%\%2.exe set cmddir=%bindir%\
-set "path=%bindir%;%bindir%\Scripts;%path%"
+set "path=%extrapaths%%path%"
 %cmddir%%cmdline%
 endlocal
 exit /b
@@ -104,3 +105,9 @@ exit /b
 :normalizepath
 set "%~2=%~dpf1"
 goto :eof
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: compute list of paths to add for all activated python versions
+:extrapath
+call :normalizepath %1 bindir
+set "extrapaths=%extrapaths%%bindir%;%bindir%\Scripts;"
+goto :eof
diff --git a/pyenv-win/libexec/pyenv---version.bat b/pyenv-win/libexec/pyenv---version.bat
index 750d4f47..a8ea1fcb 100644
--- a/pyenv-win/libexec/pyenv---version.bat
+++ b/pyenv-win/libexec/pyenv---version.bat
@@ -1,6 +1,6 @@
 @echo off
 setlocal
-set KNOWN_VER=2.64.7.2
+for /f %%v in ('type %~dp0..\..\.version') do set "KNOWN_VER=%%v"
 
 if "%1" == "--help" (
 echo Usage: pyenv --version


Test patch:
diff --git a/tests/test_pyenv_feature_exec.py b/tests/test_pyenv_feature_exec.py
index 763fc5fc..594a4932 100644
--- a/tests/test_pyenv_feature_exec.py
+++ b/tests/test_pyenv_feature_exec.py
@@ -22,7 +22,11 @@ class TestPyenvFeatureExec(TestPyenvBase):
     """
     @classmethod
     def setup_class(cls):
-        settings = {'versions': ['3.7.7'], 'global_ver': '3.7.7'}
+        settings = {
+            'versions': ['3.7.7', '3.8.9'],
+            'global_ver': '3.7.7',
+            'local_ver': "3.7.7\n3.8.9\n",
+        }
         cls._temp_env = TempPyEnv(settings)
         cls.ctx = cls._temp_env.context
         cls._temp_path = TemporaryEnvironment({"PATH": f"{os.path.dirname(sys.executable)};"
@@ -31,7 +35,8 @@ def setup_class(cls):
                                                        f"{os.environ['PATH']}"})
         cls._temp_path.__enter__()
         cls.ctx.pyenv('rehash')
-        os.unlink(str(Path(cls.ctx.pyenv_path, r'versions\3.7.7\python.exe')))
+        for v in settings['versions']:
+            os.unlink(str(Path(cls.ctx.pyenv_path, fr'versions\{v}\python.exe')))
 
     @classmethod
     def teardown_class(cls):
@@ -124,6 +129,19 @@ def test_path_not_updated(self, setup):
         stdout = result.stdout.strip("\r\n\x0c").splitlines()
         assert stdout[0] == stdout[1]
 
+    def test_many_paths(self, setup):
+        pyenv = str(self.__class__.ctx.pyenv_path / "bin" / "pyenv.bat")
+        args = [pyenv, 'exec', 'python', '-c', "import os; print(os.environ['PATH'])"]
+        result = subprocess.run(args, capture_output=True, encoding="utf8")
+        # \x0c: generated by cls in cmd AutoRun
+        stdout = result.stdout.strip("\r\n\x0c")
+        paths = stdout.split(sep=';')
+        i = 0
+        for v in ['3.7.7', '3.8.9']:
+            for relative in ['', r'\Scripts']:
+                assert paths[i].endswith(f'{v}{relative}')
+                i = i + 1
+
 
 def pyenv_exec_help():
     return "Usage: pyenv exec <command> [arg1 arg2...]"