Batch file 为什么批处理脚本中的命令是;“未被认可”;哪些是手动执行的?
我正在编写一个批处理脚本,从同一文件夹中的MSI文件安装一些应用程序 当我在命令提示符窗口中编写这些命令时,一切正常,所有命令都正常工作 但是,当我将它们写入批处理脚本时,大多数命令(如Batch file 为什么批处理脚本中的命令是;“未被认可”;哪些是手动执行的?,batch-file,cmd,windows-server-2012,Batch File,Cmd,Windows Server 2012,我正在编写一个批处理脚本,从同一文件夹中的MSI文件安装一些应用程序 当我在命令提示符窗口中编写这些命令时,一切正常,所有命令都正常工作 但是,当我将它们写入批处理脚本时,大多数命令(如XCOPY,msiexec,DISM)会突然产生如下错误消息: “XCOPY”不被识别为内部或外部命令、可操作程序或批处理文件 在谷歌搜索了一段时间后,我看到了许多与环境变量PATH相关的注释,这些注释应该包含C:\Windows\system32,我确保它包含在路径中。我还找到了很多关于写完整路径的答案,我已经
XCOPY
,msiexec
,DISM
)会突然产生如下错误消息:
“XCOPY”不被识别为内部或外部命令、可操作程序或批处理文件
在谷歌搜索了一段时间后,我看到了许多与环境变量PATH
相关的注释,这些注释应该包含C:\Windows\system32
,我确保它包含在路径中。我还找到了很多关于写完整路径的答案,我已经试过了,但没有成功
我正在Windows server 2012上工作
这是我的批处理文件的代码:
@echo off
set path=C:\ rem default path
rem get the path as parameter to the script:
set argC=0
for %%x in (%*) do Set /A argC+=1
if %argC% gtr 0 (set path=%1%)
IF %ERRORLEVEL% NEQ 0 (
echo %me%: something went wrong with input directory
)
echo Destenation: %path%
SETLOCAL ENABLEEXTENSIONS
SET me=%~n0
SET parent=%~dp0
echo %me%: starting installation of Python 2.7 64bit and Apache 64 bit
REM install .net 3.5
DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:installationMediaDrive:\sources\sxs
msiexec /i ".\py\python-2.7.amd64.msi" TARGETDIR=%path%/Python27 /passive /norestart ADDLOCAL=ALL
mkdir %path%\Apache24
XCOPY /e /Q ".\Apache24" %path%\Apache24
set path=C:\ rem default path
看起来批处理文件应该支持可选指定的安装目录路径作为第一个参数。用于检查此可选文件夹路径是否存在的代码非常混乱。显然有更简单的方法来检查可选参数,如下所示
主要问题是重新定义环境变量PATH
,这导致在执行批处理文件时,命令解释器cmd.exe
无法再找到存储在目录%SystemRoot\System32
中的Windows标准控制台应用程序和其他标准Windows目录
通常,如果此完整的文件规范字符串包含空格字符或其中一个字符,则需要指定一个应用程序以双引号括起的完整路径、文件名和文件扩展名执行`~代码>如上次输出帮助页面上关于在命令提示窗口中运行的最后一段所述cmd/?
但主要是为了让人类用户更容易从命令提示符窗口中手动执行应用程序和脚本,Windows命令解释器还可以在没有路径和文件扩展名的情况下找到要自己运行的应用程序或脚本
因此,如果用户只输入xcopy
,或者批处理文件只包含xcopy
,Windows命令解释器首先在当前目录中搜索与模式xcopy.*
匹配的文件,该模式的文件扩展名在以分号分隔的环境变量列表pathText
中定义,如果在以分号分隔的环境变量列表的所有目录中未找到合适的文件,则在下一个目录中搜索路径
有3个环境变量PATH
:
存储在Windows注册表中的系统路径为:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
HKEY_LOCAL_MACHINE\Environment
默认情况下,系统路径
中的文件夹路径用于独立于已用帐户的所有进程
存储在Windows注册表中的用户路径
:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
HKEY_LOCAL_MACHINE\Environment
默认情况下,用户路径
中的文件夹路径仅用于使用设置了用户路径
的帐户运行的所有进程
在当前运行进程的活动环境中,本地路径
仅保留在内存中
系统和用户路径
由Windows连接到单个进程的本地路径
每次进程启动新进程(如Windows资源管理器启动Windows命令解释器以执行批处理文件)时,Windows都会为新进程创建当前运行进程的环境表的副本。因此,无论一个进程在其自身的环境变量本地副本上更改了什么,都不会对所有其他已经运行的进程产生影响。对环境变量的局部更改仅对自己的流程以及由流程修改其变量启动的所有流程有效
启动批处理文件时,变量PATH
和PATHEXT
的值与在启动批处理文件时使用的相同用户帐户下打开的命令提示符窗口中运行时显示的值相同。命令set PATH
列出了所有以PATH
开头的变量,名称不区分大小写
现在让我们看一下批处理文件的第二行:
@echo off
set path=C:\ rem default path
rem get the path as parameter to the script:
set argC=0
for %%x in (%*) do Set /A argC+=1
if %argC% gtr 0 (set path=%1%)
IF %ERRORLEVEL% NEQ 0 (
echo %me%: something went wrong with input directory
)
echo Destenation: %path%
SETLOCAL ENABLEEXTENSIONS
SET me=%~n0
SET parent=%~dp0
echo %me%: starting installation of Python 2.7 64bit and Apache 64 bit
REM install .net 3.5
DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:installationMediaDrive:\sources\sxs
msiexec /i ".\py\python-2.7.amd64.msi" TARGETDIR=%path%/Python27 /passive /norestart ADDLOCAL=ALL
mkdir %path%\Apache24
XCOPY /e /Q ".\Apache24" %path%\Apache24
set path=C:\ rem default path
此行重新定义了本地路径
环境变量。因此,对执行批处理文件的命令进程有效的环境变量PATH
,并且由该批处理文件启动的所有应用程序不再包含C:\Windows\System32;C:\Windows代码>,但现在只包含这个非常奇怪的单一文件夹路径
C:\ rem default path
rem
是cmd.exe
的内部命令,必须写在单独的一行上。在C++或JavaScript中,在批处理代码中,如“代码> //< /代码>”,不可能有行注释。有关此命令的帮助,请在命令提示符窗口中运行rem/?
在没有安装文件夹路径作为第一个参数的情况下运行批处理文件时,结果是Windows命令解释器搜索dism.*
,msiexec.*
和xcopy.*
仅在当前目录中,因为肯定没有名为rem默认路径的目录
在驱动器根目录的开头有很多空格/制表符C:
结论:最好使用path
作为安装文件夹路径的变量名
C:\ rem default path
批处理代码中的另一个错误是使用%1%
指定批处理文件的第一个参数。这是错误的,因为批处理文件的参数引用为%1
,%2
。。。闯入