1

在批处理脚本上,与%~dp0. 问题是,在我的脚本的某些部分,%~dp0返回它应该返回的内容,即包含正在运行的脚本的文件夹的驱动器的完整路径(这里:'C:\Data\name\App\App\' )。在代码的其他一些部分,%~dp0只返回包含脚本的驱动器(这里:'C:\')。

这是我的脚本(有史以来的第一个批处理脚本:D):

@ECHO OFF

ECHO.
:: run the script with the command new-built.bat /all -arch x86 -config release


SETLOCAL EnableDelayedExpansion
SET options=arch version config
SET what_to_build=all lib
:: the three following lines returns what is expected
echo %%~dp0 is returning : %~dp0
echo %%~p0 is returning : %~p0
echo %%~d0 is returning : %~d0
echo The absolute path to this script is : %~dp0%0

:: read what to build, ie all or lib only
FOR %%i in (%what_to_build%) do if %1==/%%i (
SHIFT
GOTO %%i
)


::the following sections (:readoptions and :optlp) work together to collect the options entered in the command, used to launch this script. It saves the values the two arrays "options" and "what_to_build" array

:readoptions
echo Entered the read options label
rem -- initialises variables arch, version and config with empty string
FOR %%i IN (%options% badoptions) DO (SET %%i=)
:optlp
echo Entered the read options loop
SET _parm1=%1
IF NOT DEFINED _parm1 GOTO :END
IF DEFINED _parm1 FOR %%i IN (%options%) DO IF .%_parm1%==.-%%i SET %%i=%2
IF DEFINED %%i shift&shift&(SET _parm1=)
IF DEFINED _parm1 SET badoptions=%badoptions% %1&SHIFT
GOTO :optlp

:all
echo Entered the all label ...
CALL :readoptions %*
echo About to build complete app for x86 in release config
set CYGWIN_DIR="%~dp0" 
:: I want this line to return "C:\Data\name\App\App\" without quotes, but it's returning "C:\"
echo Cygwin dir (not returning what I want): %CYGWIN_DIR%
rem build lib
call %~dp0\build_scripts\build_lib_x86.bat
rem build the Visual Studio Solution
start "Build App x86 - release config" /W "%~dp0%build_scripts\build_app_x86_release.bat"


goto :end

:END
echo Program is done
endlocal

这是我得到的痕迹:

%~dp0 is returning : C:\Data\name\App\App\
%~p0 is returning : \Data\name\App\App\
%~d0 is returning : C:
The absolute path to this script is : C:\Data\name\App\App\new-build.bat
Entered the all label ...
Entered the read options label
Entered the read options loop
Entered the read options loop
Entered the read options loop
Entered the read options loop
Entered the read options loop
Entered the read options loop
Program is done
About to build complete app for x86 in release config
Cygwin dir (not returning what I want) : "C:\"
The system cannot find the path specified.
Program is done

一定有什么事情发生了,我错过了。任何帮助将不胜感激。

最好的

4

1 回答 1

1

Ooooh - 大麻烦!

@ECHO OFF

ECHO.
:: run the script with the command new-built.bat /all -arch x86 -config release


SETLOCAL EnableDelayedExpansion
SET options=arch version config
SET what_to_build=all lib
:: the three following lines returns what is expected
echo %%~dp0 is returning : %~dp0
echo %%~p0 is returning : %~p0
echo %%~d0 is returning : %~d0
echo The absolute path to this script is : %~dp0%0

给定 new-built.bat /all -arch x86 -config release 然后%1/all

:: read what to build, ie all or lib only
FOR %%i in (%what_to_build%) do if %1==/%%i (
SHIFT
GOTO %%i
)

所以,因为%1is /all,这将:all%1=-arch %2=x86 %3=-config %4=releaseBUT%*=/all -arch x86 -config release

那时同上,但%1/lib到达:lib

但是对于 %1 的任何其他值,处理将直接从这里收费到下一条语句....


...所以我们到达:all%1=-arch %2=x86 %3=-config %4=release但是%*=/all -arch x86 -config release

:all
echo Entered the all label ...
CALL :readoptions %*

由于 :readoptions 被调用,%*每个ORIGINAL参数都被传递给 :readoptions 但是goto :EOF你没有把它修改为 'goto END and hence the messageProgram is done is displayed - and processing returns to the statement following theCALL'

echo About to build complete app for x86 in release config
set CYGWIN_DIR="%~dp0" 
:: I want this line to return "C:\Data\name\App\App\" without quotes, but it's returning "C:\"
echo Cygwin dir (not returning what I want): %CYGWIN_DIR%
rem build lib
call %~dp0\build_scripts\build_lib_x86.bat
rem build the Visual Studio Solution
start "Build App x86 - release config" /W "%~dp0%build_scripts\build_app_x86_release.bat"


让我们重新开始...

我相信您实际上希望为 CYGWIN_DIR 分配您的 CYGWIN 目录名称的值。可能我们可以解决这个问题,但如果它永久设置在您的环境中会更好。简单的方法是:

SETX CYGWIN_DIR "wherever your cygwin dir is"
SETX CYGWIN_DIR "wherever your cygwin dir is" /M

(第一个为当前登录会话中的新 CMD 实例分配值,第二个为将来的登录会话分配值。IOW,执行第二个并重新启动...如果您愿意,可以使用 SETX CYGWIN_DIR "" 删除该条目)

@ECHO OFF
ECHO.
:: run the script with the command new-built.bat /all -arch x86 -config release

SETLOCAL EnableDelayedExpansion
SET options=arch version config
SET SLASHOPTS=ALL LIB
(SET SWITCHES=)
:: %CD% is the magic pseudovariable for the current directory.
:: quote it if you wish
SET CYGWIN_DIR=%CD%
:: The above line of course only if you want CYGWIN_DIR to be set to the current directory
CALL :READOPTIONS %*
:: NOTE THAT %badoptions% now contains a list of the items NOT
:: involved in the OPTIONS, SWITCHES or SLASHOPTIONS
:: read what to build, ie all or lib only
:: ONE WAY...
IF DEFINED ALL goto ALL
IF DEFINED LIB goto LIB
:: ANOTHER WAY to do the same thing
for %%i in (%SLASHOPTS%) DO if defined %%i goto %%i
:: EEK! Neither ALL not LIB was specified - what to do?
echo EEK! Neither ALL not LIB was specified - exiting!
goto :EOF


:all
echo Entered the all label ...
echo About to build complete app for x86 in release config
echo Cygwin dir (not returning what I want): %CYGWIN_DIR%
rem build lib
:: I'll assume %CYGWIN_DIR%\build_scripts is where you're keeping this batch
call %CYGWIN_DIR%\build_scripts\build_lib_x86.bat
rem build the Visual Studio Solution
start "Build App x86 - release config" /W "%CYGWIN_DIR%\build_scripts\build_app_x86_release.bat"


goto end

:LIB
echo LIB processing not yet defined
goto end

:END
echo Program is done
endlocal

:readoptions
echo Entered the read options label
rem -- initialises variables arch, version and config with empty string
:readoptions
FOR %%i IN (%options% %slashopts% %switches% badoptions) DO (SET %%i=)
:optlp
SET _parm1=%1
IF NOT DEFINED _parm1 GOTO :EOF
FOR %%i IN (%switches%) DO IF /i %_parm1%==-%%i SET %%i=Y&(SET _parm1=)
IF NOT DEFINED _parm1 shift&GOTO :optlp
FOR %%i IN (%slashopts%) DO IF /i %_parm1%==/%%i SET %%i=Y&(SET _parm1=)
IF NOT DEFINED _parm1 shift&GOTO :optlp
FOR %%i IN (%options%) DO IF /i %_parm1%==-%%i (
SET %%i=%2
IF DEFINED %%i shift&shift&(SET _parm1=)
)
IF DEFINED _parm1 SET badoptions=%badoptions% %1&SHIFT
GOTO :optlp

请注意,我稍微修改了 :readoptions 以便您可以设置-option anoptionvalueor-switch/slashoption

另请注意,您可以将部分从 :readoptions 传输到最后一个独立的批处理文件,例如readoptions.bat将该文件放在您的任何位置pathset path从提示中查看),然后任何批处理都可以执行

CALL READOPTIONS %*

阅读您的选项/开关/斜线选项,因为您已在变量和批处理中单独指定它们options-并将包含任何剩余参数...switchesslashoptsbadoptions

(Note on colons: call :routine parameterlist calls an INTERNAL routine with 'private' parameters parameterlist call routine parameterlist calls an EXTERNAL routine with 'private' parameters parameterlist; ie. the [batch] file 'routinefrom somewhere on thepath`

goto :eof

Is an inbuilt facility to go to the physical end-of-file. This terminates a CALL and returns to the line following OR exits the batch completely. )

于 2013-03-18T18:01:59.940 回答