【问题标题】:Batch Script for silent installing 7zip is not continue after running 7zip setup运行 7zip 设置后,用于静默安装 7zip 的批处理脚本不会继续
【发布时间】:2018-07-20 21:52:00
【问题描述】:

我正在尝试创建一个静默运行多个 setup .exe 的脚本,无论出于何种原因,当我在批处理文件中静默执行 7zip 安装时,之后不会执行其他命令。

有点不知所措。我试过暂停、回声、其他只是回声的子例程(返回后工作并执行命令)。

但无论出于何种原因,在我执行 7zip.exe /S 之后,即使从我为安装它所做的子例程返回,它也会退出执行命令。

@echo OFF


SET 7ZipName=7z*.exe

SET x86SetupFilePath=C:\PSDARS-Setup\x86\
SET x64SetupFilePath=C:\PSDARS-Setup\x64\

SET x647ZipPath=C:\Program Files\7-Zip\
SET x867ZipPath=C:\Program Files (x86)\7-Zip\

:: 1. Check for OS architecture
reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set OS=32BIT || set OS=64BIT

if %OS%==32BIT GOTO :32BIT

if %OS%==64BIT GOTO :64BIT

:32BIT

:: Check arguments 1 = Installation Directory Path. If not set use base above 
IF NOT %1.==. SET x86SetupFilePath=%~1

::Install 7zip
CALL :Install7Zip 

setx PATH "%PATH%;%x647ZipPath%" /m

GOTO :ProgramEnd


:64BIT

:: Check arguments 1 = Installation Directory Path 
IF NOT %1.==. SET x64SetupFilePath=%~1

::Install 7zip
CALL :Install7Zip 

CALL :Test

Echo 7zip Installation Complete

::setx PATH "%PATH%;%x647ZipPath%" /m

GOTO :ProgramEnd

:Test
Echo a
GOTO :EOF

:: Author: Jacob Howarth
:: Date: 07/20/18
:: Description: This procedure will install the correct version of
:: the 7zip installer silent based on the architecture of the OS
::
:Install7Zip
IF %OS%==32BIT cd "%x86SetupFilePath%"

IF %OS%==64BIT cd "%x64SetupFilePath%"

for %%f in (%7ZipName%) do SET File=%~f     

%File% /S

ECHO.%ERRORLEVEL%

GOTO :EOF
:: End of Install7Zip

echo 7zip Installation Complete

:ErrorInstall7Zip
echo Error installing 7zip for %OS% OS. x64 path = %x64SetupFilePath%, x86 path =%x86SetupFilePath%.

:ProgramEnd

【问题讨论】:

  • 我能看到的每条代码路径都以GOTO :ProgramEnd结尾,:ProgramEnd之后就没什么可做的了。你预计会发生什么?
  • 为什么要检查 CPU 的位数? 64位CPU可以安装32位操作系统.
  • 如果代码:SET File=%~f,则此行中缺少百分号。也不要以数字开头的变量名。它可以看作是一个命令行参数。
  • 命令行setx PATH "%PATH%;%x647ZipPath%" /m 绝对是NO GO - NEVER EVER。由于各种原因,您正在使用该命令行破坏 system 环境变量 PATH。参见例如Why are other folder paths also added to system PATH with SetX and not only the specified folder path?Adding the current directory to Windows path permanently。确实没有必要将 7-Zip 程序文件路径添加到 system PATH,否则 7-Zip 设置会这样做。
  • 我很欣赏建设性的改变,但这些都没有真正回答为什么在执行 7zip 的设置后它不执行任何命令的问题。 @Mofi 7zip 显然不会被添加到任何路径变量系统或以其他方式静默安装。我已经检查过了,我没有看到它。我会检查它是否与导致错误的for变量有关。

标签: windows batch-file command-line


【解决方案1】:
@echo off
setlocal

:: Check for OS architecture.
set "SetupFilePath=%~1"

if not defined SetupFilePath (
    if defined ProgramFiles(x86^) (
        set "SetupFilePath=C:\PSDARS-Setup\x86"
    ) else (
        set "SetupFilePath=C:\PSDARS-Setup\x64"
    )
)

:: Change working directory.
cd /d "%SetupFilePath%" || (
    >&2 echo Failed to change directory.
    exit /b 1
)

:: Get setup file name.
set "SevenZipName=7z*.exe"
set "File="

for %%F in ("%SevenZipName%") do set "File=%%~F"

if not defined File (
    >&2 echo File not defined.
    exit /b 1
)

:: Install 7zip.
"%File%" /S

if errorlevel 1 (
    >&2 echo 7zip errorlevel: %errorlevel%
    exit /b 1
)

:: Add to PATH environment variable.
set "SevenZipPath=%ProgramFiles%\7-Zip"

if exist "%SevenZipPath%" (
    call :add_path "%SevenZipPath%" "%%ProgramFiles%%\7-Zip"
)

echo 7zip Installation Complete
exit /b 0


:add_path
set "main_key=HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
set "data="

:: Query the HKLM Path and get the key name, data type and data.
for /f "tokens=1,2,*" %%A in ('reg query "%main_key%" /v Path') do (
    if /i "%%~A" == "Path" (
        set "key_name=%%~A"
        set "data_type=%%~B"
        set "data=%%~C"
    )
)

if not defined data (
    >&2 echo Path data for write to registry is undefined.
    exit /b 1
)

:: Remove trailing semi-colon.
if "%data:~-1%" == ";" set "data=%data:~,-1%"

:: Check target is already in Path.
for %%A in ("%data:;=" "%") do for %%B in ("%~1" "%~2") do (
    if "%%~A" == "%%~B" (
        echo Directory "%%~B" is in Path.
        exit /b 0
    )
)

:: Set new_data to a value to suit data type.
if /i "%data_type%" == "REG_EXPAND_SZ" (
    set "new_data=%~2"
) else set "new_data=%~1"

if not defined new_data (
    >&2 echo Path new_data to write to registry is undefined.
    exit /b 1
)

:: Remove trailing backslash.
if "%new_data:~-1%" == "\" set "new_data=%data:~,-1%"

:: Backup and update Path.
if not exist "%~dp0Environment_Backup.reg" (
    echo Backing up key to Environment_Backup.reg.
    reg export "%main_key%" "%~dp0Environment_Backup.reg"
)

echo Adding "%new_data%" to Path.
>nul reg add "%main_key%" /v "Path" /t "%data_type%" /d "%data%;%new_data%" /f
exit /b 0

重组代码以删除goto 流。

检查ProgramFiles(x86) 的操作系统架构。

命令setx 对简单变量是可以的,尽管使用 PATH 变量,需要更多代码来检查值 键并仅在需要时添加到现有值。 reg 值类型和可能的变量等注意事项 在值可能需要检查。一个 reg 导出文件是 在添加更改之前创建为备份。

使用不以数字开头的用户变量名。这 原因是 %7ZipName% 这样的名称可能是 解释为%7ZipName%%7 是第一个有效的 扩展作为第 7 个参数。这可能会导致语法 错误。

使用 x64 操作系统测试。操作系统环境可能需要重新启动才能 更新更改或运行 SystemPropertiesAdvanced 并单击 环境变量然后OK两次 更新。

【讨论】:

  • 安装 7Zip 后如何让它执行?之后我什至无法得到回声来执行,所以我很困惑echo 7zip Installation Complete 是如何工作的,因为到目前为止它并没有那么不同。是因为我没有做setlocal吗?
  • 在您的源代码中,%7 毒化了for 循环,而echogoto :eof 之后,因此它实际上会转到文件末尾并完成脚本。跨度>
  • 好的,理解 for 循环。但是,这是否意味着该站点上的有关呼叫的部分有误? ss64.com/nt/call.html 它说你可以在例程结束时使用GOTO :EOF 来完成exit /b
  • goto :eofexit /b 具有相似的行为,因此可以互换。在您的来源中,您调用:Install7Zip,它继续向下到goto :eof,然后返回到调用者行。 :64bit 标签有回声,而:32bit 标签没有。 reg query 可能有 goto:32bit 标签。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
相关资源
最近更新 更多