我应该如何使用批处理脚本来创建其他脚本?

时间:2012-03-05 02:23:21

标签: windows batch-file

我正在创建一个我想成为双重用途的脚本:

  1. 该脚本将使用用户输入选项执行命令以更改某些设置。这部分差不多完成了。

    • 该脚本通过SETLOCAL / ENDLOCALSET /P将用户选择收集到本地环境变量中,稍后在脚本中调用变量以执行命令。

    • 收集用户选项后,会有一个验证步骤显示这些选项,并在继续执行命令之前要求用户进行确认。

  2. 该脚本将为用户提供一个选项,可以自动创建一个内置选项的新脚本,以备将来使用。

  3. 这是我目前实现目标#2的计划概念,虽然我不确定如何编写它:

    1. 构建一个模板脚本,可以将其复制以开始创建自定义脚本。

      • 在模板脚本的最开始,SETLOCAL将隔离最终脚本创建的环境变量,因此在脚本运行完毕后它们不会保留。

      • SETLOCAL之后将立即成为GOTO命令,该命令指向脚本最末端的标签。标签将是已完成脚本中变量定义部分的开头。

      • GOTO命令后将是一个名为STARTEXEC的标签,在变量定义完成后将跳转到该标签。

      • 就在变量部分标签之前是标记的部分,其中包含一些退出脚本的命令。

    2. 进入当前脚本:

      • 在验证步骤中添加CHOICE,询问用户是否要创建静态脚本。如果是,请通过SET /P提示用户输入文件名,然后通过GOTO在此脚本的执行流程中包含脚本构建命令。
    3. 使用类似这些的命令来构建静态脚本的变量部分:

      COPY ScriptTemplate.bat %UserFileName%.bat
      ECHO SET VAR1=%UserVar1% >> %UserFileName%.bat
      ECHO SET VAR2=%UserVar2% >> %UserFileName%.bat

    4. 再添加一行以确保静态脚本跳转到命令执行。

      ECHO GOTO STARTEXEC >> %UserFileName%.bat

    5. 我的问题在这里:

      1. 我的方法是否相当合理,还是通过批处理脚本更好的方法?

      2. 在返回到变量部分之前,我应该使用什么来退出静态脚本?我知道我需要ENDLOCALEXIT会在这里工作吗,还是有其他更合适的东西?

2 个答案:

答案 0 :(得分:1)

模板的想法似乎是简单的方法(不确定简短,但这可能就是我接近它的方式。)根据原始模板创建一个单独的模板,删除所有的SET / P命令。 / p>

编辑:

删除了旧答案。

在模板的末尾,写下:

GOTO:EOF

:User_Defined_Variables

在文件的开头,写一下:

CALL:User_Defined_Variables

在原始脚本中,在用户确认创建自定义脚本后,制作模板文件COPY /y template.bat userscript.bat的副本,将所有用户的变量发送给它。

(ECHO var1 = %uservar1% 
 ECHO var2 = %uservar2%
 Echo var3 = %uservar4%)>> userscript.bat
GOTO:EOF

因此,当用户运行脚本时,CALL:User_Defined_Variables将设置用户的脚本参数并继续使用脚本的其余部分。

答案 1 :(得分:0)

Iszi,

我有一个类似于我工作的功能...我们有一组不同的自定义变量,我们用它来启动我们处理的每个客户的其他功能。我用Batch编写了一个复杂的脚本,允许我自己和同事实现这一点,但是在我看来,不需要创建一个单独的批处理文件。

我认为有两种方法可以实现您的目标:

  1. 您可以在开头设置所有变量,然后从那里编辑

  2. 您可以在每次/写一个新脚本时提示输入

  3. 无论哪种方式,你都写出一个批处理文件来编写另一个批处理文件是愚蠢的,并在代码中留下各种可能的错误。您不仅要对一个批处理脚本进行错误检查,还会有另一个批处理脚本。

    以下是您可以做的一些示例:

    1

    @ECHO off
    TITLE Install Script
    COLOR 0A
    SETLOCAL
    
    REM ---------------------------
    REM  *** EDIT VARIABLES BELOW ***
    REM ---------------------------
    
    :sharepath
    set sharepath=\\SCIncapps\sharepath
    REM SHAREPATH = The location of the files that will be copied to the client machine. List of files you will need in your SCIncIntViewer folder: 
    REM vcredist_x86.exe, msxml6.msi,  Browser Access Client Controls.msi,  Automated Update Service.msi, bac.ico, dotnetfx35.exe, dotNetFx40_Full_x86_x64.exe,  Episys Client.msi
    REM This Sharepath is where the Script needs to be located and has to be an already existing directory
    
    :primaryStaging
    set primaryStaging=SCIncweb
    REM primaryStaging = The name of the back office server that handles AutoUpdate. This is usually the same as websrvr, except in distributed  environments
    
    :webserver
    set websrvr=SCIncweb
    REM websrvr = The name of the Web Server; i.e. SCIncweb, SCInc14Doc1, 10.1.1.1, 192.168.1.20, etc.
    
    :install_variables
    set dotnet35=F
    REM Defines the installation of .NET 3.5 SP 1 as True(T) or False(F)
    set dotnet40=F
    REM Defines the installation of .NET 4.0 as True(T) or False(F)
    set regedit=F
    REM Defines the creation of the Registry File to edit all IE settings as True(T) or False(F)
    set SSL=F
    REM Defines the use of SSL for the BAC URL; SSL is set as True(T) or False(F)
    set org=0000
    REM Defines the Organization for the BAC url shortcut that is created on the desktop for all users (enter the numeric org #)
    set favorite=T
    REM This will put the  Browser Access Client URL in their favorite folder and on their browser's quick link bar as True(T) or False(F)
    set reboot=F
    REM Defines whether or not the script will reboot the machine after it's complete as True(T) or False(F)
    REM If using the PsExec.exe to push this script this will force the Domain Administrator to logoff the machine
    set reloadAll=F
    REM This defines if the _Installed_Files.txt will be overwritten to install all products again as True(T) or False(F)
    REM NOTE This will copy down all items and install everything except .NET 3.5 SP1 and .NET 4.0
    
    :creditUnion_Variables
    set episys=F
    REM Defines the installation of Episys Integration for  as True(T) or False(F)
    
    :bank_Variables
    set silver2020=F
    REM Defines the installation of SCInc Integration for  as True(T) or False(F)
    set coreDirector=F
    REM Defines the use of Core Director for banks as True(T) or False(F)
    set iseries=1.1.1.1
    REM Defines the IP address of the iSeries if in-house Some Company, Inc Core, otherwise irrelevant
    set dualinQuiry=F
    REM Defines the deletion of the old SCInc Viewer if NOT using Dual Inquiry as True(T) or False(F)
    set thinClient=F
    REM Defines the /install and /execute flags on a Terminal Server as True(T) or False(F)
    set vportsPath=%sharepath%
    REM Defines the vports.xml file's location, this variable should be kept as the sharepath unless the client specifies otherwise
    
    :Logs
    set PCaudit=T
    REM Defines whether or not you want just the PC name to be logged to a file as True(T) or False(F)
    REM Creates a list of all the PC's that this script has been run on and puts it in the sharepath folder
    
    REM ---------------------------
    REM *** DO NOT EDIT BELOW ***
    REM ---------------------------
    
    IF /I '%scanStation%'=='T' goto:eof
    REM If running the Scan Station Install tool only the variables are read and then the  Scan Station Install Tool.bat will resume
    goto thinClient_inst
    
    :thinClient_inst
    IF /I '%thinClient%'=='F' goto date_time
    change user /install
    
    :date_time
    FOR /F %%A IN ('TIME/T') DO SET time=%%A
    REM Sets the time in a proper format for Error Logging
    FOR /F "tokens=1-4 delims=/ " %%B IN ('DATE /t') DO SET date=%%C/%%D/%%E
    REM Sets the date in a proper format for Error Logging
    
    :errorLog
    REM Logs the error messages for each product that the script attempts to install
    IF exist %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt goto PCaudit
    echo.Microsoft Website for Errors:> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt
    echo.http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt
    echo.(Popular Error: 9009, 1616 :: File does not exist in directory)>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt
    echo.--------------------------------------------------------------->> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt
    set cleanInstall=0
    REM Checks if the ErrorLog file already exists, if not it writes the fist 2 lines which contain the URL for determining the Errors from Microsoft
    goto PCaudit
    
    :PCaudit
    REM Logs the Computer Name to the Installed_PC text file
    REM This checks to make sure that the PC name doesn't already exist in that file and if it does it puts it into another file called %org%_ _Repeat_Installs_Log.txt
    verify >nul
    IF /I '%PCaudit%'=='f' set PCaudit=F
    IF /I '%PCaudit%'=='F' goto start
    IF /I '%PCaudit%'=='t' set PCaudit=T
    set repeat=F
    findstr /x "%computername%" %sharepath%\%org%_ _Installed_PCs_AuditList.txt 
    IF '%ERRORLEVEL%'=='0' set repeat=T
    IF /I '%repeat%'=='T' echo.%date% - %time% - %computername%>> %sharepath%\%org%_ _Repeat_Installs_Log.txt
    IF /I '%repeat%'=='T' goto start
    IF /I '%repeat%'=='F' echo.%computername%>> %sharepath%\%org%_ _Installed_PCs_AuditList.txt
    goto start
    
    :start
    REM Changes all variables for True(T) and False(F) to capital letters since batch is case sensitive
    set HKEY=HKEY_LOCAL_MACHINE
    REM This script is meant to be run by a user with ADMIN privledges; 
    REM " HKEY_LOCAL_MACHINE " registry items can only be edited by an admin
    
    :_done
    IF NOT exist "c:\SCInc\ \_done" md c:\SCInc\ \_done
    IF NOT exist "c:\SCInc\ \_done\ _Installed_Files.txt" echo. Installed Files for %computername%: > c:\SCInc\ \_done\ _Installed_Files.txt
    IF /I '%reloadAll%'=='T' echo. Installed Files: > c:\SCInc\ \_done\ _Installed_Files.txt
    goto iviewerUrl
    REM Creates the _done folder and the _Installed_Files.txt which will be local to the PC and will keep the products they install to prevent reinstallation
    REM Delete this folder to reinstall all products or delete the line of text inside to reinstall a particular product
    
    :iviewerUrl
    set iviewerUrl=http://%websrvr%
    IF /I '%SSL%'=='T' (set iviewerUrl=https://%websrvr%)
    REM This sets the 'iviewerUrl' variable depeneding on if you have SSL enabled or not
    set SCIncUrl=/bac/user/User_SO.asp?%OrgName=
    REM This sets the rest of the URL for the browser shortcut (the '?' doesn't get a long with batch scripts)
    
    :copy
    REM Copies the files from the sharepath to the local machine
    echo.
    echo.Copying Necessary Files for Installation
    echo.This could take a few minutes...
    md C:\SCInc\ 
    md C:\SCInc\Temp
    REM Creates the ' \SCInc\ ' and ' \SCInc\Temp ' directories
    goto 1
    
    :1
    verify >nul
    findstr /x "copy_vcredist" "c:\SCInc\ \_done\ _Installed_Files.txt" 
    IF '%ERRORLEVEL%'=='0' goto 2
    echo.Copying vcredist_x86.exe
    copy %sharepath%\vcredist_x86.exe c:\SCInc\temp
    REM Copies the C++ Redistributable installer
    IF '%ERRORLEVEL%'=='0' echo.copy_vcredist>> C:\SCInc\ \_done\ _Installed_Files.txt
    IF NOT '%ERRORLEVEL%'=='0' echo.%date% - %time% - %computername% - There was an error copying vcredist_x86: Error Code %errorlevel%>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt & set cleanInstall=1
    goto 2
    :2
    verify >nul
    findstr /x "copy_msxml6" "c:\SCInc\ \_done\ _Installed_Files.txt" 
    IF '%ERRORLEVEL%'=='0' goto 3
    echo.Copying msxml6.msi
    copy %sharepath%\msxml6.msi c:\SCInc\temp
    REM Copies MSXML 6.0 Parser installer
    IF '%ERRORLEVEL%'=='0' echo.copy_msxml6>> C:\SCInc\ \_done\ _Installed_Files.txt
    IF NOT '%ERRORLEVEL%'=='0' echo.%date% - %time% - %computername% - There was an error copying msxml6.msi: Error Code %errorlevel%>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt & set cleanInstall=1
    goto 3
    :3
    verify >nul
    findstr /x "copy_BAC" "c:\SCInc\ \_done\ _Installed_Files.txt" 
    IF '%ERRORLEVEL%'=='0' goto 4
    echo.Copying  Browser Access Client Controls.msi
    copy %sharepath%\" Browser Access Client Controls.msi" C:\SCInc\temp
    REM Copies the  Browser Access Client Controls installer
    IF '%ERRORLEVEL%'=='0' echo.copy_BAC>> C:\SCInc\ \_done\ _Installed_Files.txt
    IF NOT '%ERRORLEVEL%'=='0' echo.%date% - %time% - %computername% - There was an error copying  Browser Access Client Controls.msi: Error Code %errorlevel%>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt & set cleanInstall=1
    goto 4
    :4
    verify >nul
    findstr /x "copy_AutoUpdate" "c:\SCInc\ \_done\ _Installed_Files.txt" 
    IF '%ERRORLEVEL%'=='0' goto 5
    echo.Copying  Automated Update Service.msi
    copy %sharepath%\" Automated Update Service.msi" C:\SCInc\temp
    REM Copies the  Automated Update Service installer
    IF '%ERRORLEVEL%'=='0' echo.copy_AutoUpdate>> C:\SCInc\ \_done\ _Installed_Files.txt
    IF NOT '%ERRORLEVEL%'=='0' echo.%date% - %time% - %computername% - There was an error copying  Automated Update Service.msi: Error Code %errorlevel%>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt & set cleanInstall=1
    goto 5
    :5
    verify >nul
    findstr /x "copy_icon" "c:\SCInc\ \_done\ _Installed_Files.txt" 
    IF '%ERRORLEVEL%'=='0' goto copy_dotnet35
    echo.Copying  BAC Icon
    copy %sharepath%\bac.ico %windir%\System32
    REM Copies the  Browser icon file to the System32 folder
    IF '%ERRORLEVEL%'=='0' echo.copy_icon>> C:\SCInc\ \_done\ _Installed_Files.txt
    IF NOT '%ERRORLEVEL%'=='0' echo.%date% - %time% - %computername% - There was an error copying bac.ico: Error Code %errorlevel%>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt & set cleanInstall=1
    echo.
    echo.Created the following directories:
    echo.-------------------------------------------------------
    echo.
    echo.C:\SCInc\ 
    echo.C:\SCInc\Temp
    echo.
    echo.-------------------------------------------------------
    goto copy_dotnet35
    
    :copy_dotnet35
    verify >nul
    REM Copies .NET 3.5 Service Pack 1
    reg query "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5"| findstr Install
    REM Checks for .NET 3.5 and installs it if it doesn't find it
    IF '%ERRORLEVEL%'=='0' set dotnet35=F
    IF /I '%dotnet35%'=='F' goto copy_dotnet40
    echo.Copying and installing .NET 3.5 Service Pack 1
    echo.This will take a few minutes...
    copy %sharepath%\dotnetfx35.exe C:\SCInc\Temp
    IF NOT '%ERRORLEVEL%'=='0' echo.%date% - %time% - %computername% - There was an error copying .NET 3.5 SP1: Error Code %errorlevel%>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt & set cleanInstall=1
    
    :dotnet35
    verify >nul
    REM Installs .NET 3.5 Service Pack 1
    echo.Installing .NET 3.5 Service Pack 1
    echo.This could take a few minutes...
    c:\SCInc\temp\dotnetfx35.exe /q /norestart
    IF '%ERRORLEVEL%'=='0' echo.dotnet35>> C:\SCInc\ \_done\ _Installed_Files.txt & set net35=1
    IF NOT '%ERRORLEVEL%'=='0' echo.%date% - %time% - %computername% - There was an error completing the installation of .NET 3.5 SP1: Error Code %errorlevel%>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt & set cleanInstall=1
    echo.
    echo.-------------------------------------------------------
    echo.
    goto copy_dotnet40
    
    :copy_dotnet40
    verify >nul
    REM Copies .NET 4.0
    reg query "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"| findstr Install
    REM Checks for the FULL (not client) version of .NET 4.0 and installs it if it doesn't find it
    IF '%ERRORLEVEL%'=='0' set dotnet40=F
    IF /I '%dotnet40%'=='F' goto msxml60
    echo.Copying and installing .NET 4.0
    echo.This could take a few minutes...
    copy %sharepath%\dotNetFx40_Full_x86_x64.exe c:\SCInc\temp
    IF NOT '%ERRORLEVEL%'=='0' echo.%date% - %time% - %computername% - There was an error copying .NET 4: Error Code %errorlevel%>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt & set cleanInstall=1
    
    :dotnet40
    verify >nul
    REM Installs .NET 4.0
    echo.Installing .NET 4.0
    echo.This could take a few minutes...
    c:\SCInc\temp\dotNetFx40_Full_x86_x64.exe /q /norestart
    IF '%ERRORLEVEL%'=='0' echo.dotnet40>> C:\SCInc\ \_done\ _Installed_Files.txt & set net40=1
    IF NOT '%ERRORLEVEL%'=='0' echo.%date% - %time% - %computername% - There was an error completing the installation of .NET 4: Error Code %errorlevel%>> %sharepath%\%org%_ _Installed_PCs_ErrorLog.txt & set cleanInstall=1
    goto msxml60
    

    以上脚本是部分的,已经过编辑。

    如您所见,我将所有变量设置在文件的开头。这样每次我需要改变一些东西时我都不会去代码这样做,与我的同事一样。其中一些能够改变它有些不是,那些不容易理解要改变什么,因为每个标志设置在文件的前70行。 我认为这是最好的方法是因为我可以灵活地改变事物。我有变量触发其他我可能想要稍后安装的安装。使用创建另一个脚本的脚本,您可能会发现自己无法在不重新运行第一个批处理文件的情况下更改内容。

    @echo off
    > usermessage.vbs ECHO WScript.Echo InputBox( "What is the name of the Service you want to restart?", "Service:", "MspSvc" )
    FOR /F "tokens=*" %%A IN ('CSCRIPT.EXE //NoLogo usermessage.vbs') DO SET Service=%%A
    ECHO You will restart %Service%
    DEL usermessage.vbs
    
    net stop %Service%
    net start %Service%
    
    Pause
    

    这是来自Rob Vanderwoude。他可能是我所知道的批处理脚本命令最常用的网站。我已经修改了这篇文章以获取用户的输入并使用它来编写我的变量以重新启动服务。这可以用于编写编写另一个脚本的脚本的目的。

    如果是这种情况,那么您要做的就是:

    @ECHO off
    TITLE Script Creator
    COLOR 0A
    SETLOCAL
    
    > usermessage.vbs echo.WScript.Echo InputBox( "Pick something to test SETLOCAL/ENDLOCAL on?", "Variable:", "OUTSIDEVARIABLE" )
    FOR /F "tokens=*" %%A IN ('CSCRIPT.EXE //NoLogo usermessage.vbs') DO SET outsideVar=%%A
    echo.Your variable is %outsideVar%
    DEL usermessage.vbs
    
    echo.%outsideVar% is still set outside
    
    echo.@echo off>c:\temp\newbatch.bat
    echo.COLOR 1B>>c:\temp\newbatch.bat
    echo.SETLOCAL>>c:\temp\newbatch.bat
    echo.cls>>c:\temp\newbatch.bat
    echo.set insideVar=%%outsideVar%% >>c:\temp\newbatch.bat
    echo.^> usermessage.vbs echo.WScript.Echo InputBox( "Pick something to test SETLOCAL/ENDLOCAL on?", "Variable:", "INSIDEVARIABLE" ) >>c:\temp\newbatch.bat
    echo.FOR /F "tokens=*" %%%%A IN ('CSCRIPT.EXE //NoLogo usermessage.vbs') DO SET insideVar=%%%%A >>c:\temp\newbatch.bat
    echo.DEL usermessage.vbs >>c:\temp\newbatch.bat
    echo.echo.Your variable is %%insideVar%% >>c:\temp\newbatch.bat
    echo.echo.You have set the Second Variable: %%insideVar%% in this new batch file! >>c:\temp\newbatch.bat
    echo.echo.%%insideVar%% is now Inside the new batch >>c:\temp\newbatch.bat
    echo.Pause >>c:\temp\newbatch.bat
    echo.ENDLOCAL >>c:\temp\newbatch.bat
    
    echo.You are about to run the new batch file
    pause
    call c:\temp\newbatch.bat
    
    cls
    pause
    echo.You created a batch file that set your outsideVar variable in it
    echo.%outsideVar% is still set outside
    
    ENDLOCAL
    REM Install Batch Script
    REM Created by Trevor G.
    

    在这个脚本中,我们有一种独特的方法可以确保每行都写到新批处理脚本的末尾,而且你需要记住这里的关键内容......有时你需要使用^(克拉)和时间,你需要加倍你的%%以确保你的变量都将被传递,并且你还没有在你的脚本中触发另一个命令,然后再将它写入新的。< / p>