如何编写批处理文件以显示可执行文件路径和处理Python脚本的Python版本?
这个脚本应该能显示出可执行文件的路径和Python的版本信息,适用于通过直接调用Python运行的脚本(比如用python myscript.py
命令)以及直接运行的脚本(比如直接输入myscript.py
)。这个脚本不应该对系统的配置做太多假设。例如,它应该能处理没有可用Python的情况。
背景说明
我在尝试不同的方式来设置运行Python脚本的环境,觉得有一个脚本能告诉我当前的配置会很有帮助。我关注的是操作系统提供的标准方式,比如PATH
环境变量,以及文件类型和处理程序的关联(像assoc
和ftype
命令,还有PATHEXT
环境变量)。所以这里不讨论pylauncher
。
2 个回答
2
这可能正是你想要的内容:
python -c "import sys; print sys.executable"
2
这是我的第一个解决方案:
解决方案 1
@echo off
set test_script=.pyexe.py
rem Let's create temporary Python script which prints info we need
echo from __future__ import print_function; import sys; print(sys.executable); print(sys.version) > %test_script%
echo Python accessible through system PATH:
python %test_script%
echo ---
echo Python set as handler for Python files:
%test_script%
del %test_script%
set test_script=
不过我遇到了一个问题。当没有有效的Python解释器和Python文件关联时,尝试用 some_script.py
打开Python文件时,会弹出一个打开方式的系统对话框。解决这个问题需要对批处理文件有很好的了解。因此,我为了找到解决办法,问了以下几个问题:
- 如何在命令窗口打开文件时防止弹出“打开方式”对话框?
- 如何在批处理文件的if语句中转义带括号的变量?
- 为什么在这个情况下批处理文件中的延迟扩展不起作用?
- 如何在批处理文件中分割带有空格的双引号字符串?
改进后的原始批处理文件现在看起来是这样的:
解决方案 1b
@echo off
setlocal
set test_script=.pyexe.py
rem Let's create temporary Python script which prints info we need
echo from __future__ import print_function; import sys; print(sys.executable); print(sys.version) > %test_script%
echo Python accessible through the system PATH:
python %test_script%
echo ---
echo Python set as a handler for Python files:
rem We need to check if a handler set in the registry exists to prevent "Open With"
rem dialog box in case it doesn't exist
rem ftype Python.File hypothetical return value:
rem Python.File="%PYTHON_HOME%\python.exe" "%1" %*
for /f "tokens=2 delims==" %%i in ('ftype Python.File') do set reg_entry=%%i
rem ...now in 'reg_entry' variable we have everything after equal sign:
rem "%PYTHON_HOME%\python.exe" "%1" %*
set "handler="
setlocal enableDelayedExpansion
for %%A in (!reg_entry!) do if not defined handler endlocal & set handler=%%A
rem ...now in 'handler' variable we have the first token:
rem "%PYTHON_HOME%\python.exe"
rem Now we expand any environment variables that might be present
rem in the handler's path
for /f "delims=" %%i in ('echo %handler%') do set expanded_handler=%%i
if exist "!expanded_handler!" (
"%test_script%"
) else (
if not "!handler!" == "!expanded_handler!" (
set "handler=!expanded_handler! ^(!handler!^)"
)
echo Handler is set to !handler! which does not exist
)
del %test_script%
这是另一种方法,避免了上述两个问题:
解决方案 2
@echo off
setlocal
echo Python accessible through the system PATH:
where python
echo ---
echo Python set as a handler for Python source files (.py):
for /f "skip=2 tokens=1,2*" %%i in ('reg query HKCR\.py /ve') do set "file_type=%%k"
for /f "skip=2 tokens=1,2*" %%i in ('reg query HKCR\%file_type%\shell\open\command /ve') do echo %%k
... 以及改进版本:
解决方案 2b
@echo off
setlocal EnableDelayedExpansion
echo Python interpreter accessible through the system PATH:
where python
if not errorlevel 1 (
python -c "from __future__ import print_function; import sys; print(sys.version)"
)
echo ---
echo Python interpreter registered as a handler for Python source files (.py):
reg query HKCR\.py /ve >nul 2>&1
if errorlevel 1 (
echo No "HKEY_CLASSES_ROOT\.py" registry key found
) else (
for /f "skip=2 tokens=1,2*" %%i in ('reg query HKCR\.py /ve 2^>nul') do set "file_type=%%k"
if "!file_type!"=="(value not set)" (
echo "No file type set for .py extension"
) else (
reg query HKCR\!file_type!\shell\open\command /ve >nul 2>&1
if errorlevel 1 (
echo No "HKEY_CLASSES_ROOT\!file_type!\shell\open\command" registry key found
) else (
for /f "skip=2 tokens=1,2*" %%i in ('reg query HKCR\!file_type!\shell\open\command /ve 2^>nul') do set "handler=%%k"
if "!handler!"=="(value not set)" (
echo No command set for !file_type!
) else (
echo !handler!
)
)
)
)