2012-03-05 79 views
5

我创建,我想成为两用的脚本:我应该如何使用批处理脚本来创建其他脚本?

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

    • 脚本通过SETLOCAL/ENDLOCALSET /P收集用户的选择到当地的环境变量,后来在脚本命令执行调用的变量。

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

  2. 的脚本会给用户一个选项来自动创建具有内置的将来方便他们选择一个新的脚本。

这是我目前的计划理念,实现目标#2,虽然我不完全知道如何把它写:

  1. 构建一个可复制的模板脚本开始创作定制的脚本。

    • 在模板脚本的一开始,SETLOCAL将被隔离在完成脚本创建环境变量,因此脚本运行完毕后,他们不存在。

    • 紧接在SETLOCAL之后的是GOTO命令,该命令指向脚本最后的标签。该标签将在完成脚本中的变量定义部分的开始。

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

    • 就在变量部分标签将与一些指令(S)退出脚本标记的部分。

  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

我的问题在这里:

  1. 是我的方法比较健全的,还是有更好的方式来做到这一点,还是通过批处理脚本?

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

+0

你是否受限于批处理文件? – Mechaflash 2012-03-08 16:02:07

+0

@Mechaflash只有我目前的知识水平和经验,但是。此问题的范围仅限于批处理文件。 – Iszi 2012-03-08 17:42:55

+0

我给了一个答案,但是,我会建议在未来的项目中寻找AutoIT。这很容易拾取,而且你看起来足够精通。 – Mechaflash 2012-03-08 19:48:26

回答

0

Iszi,

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

有2种方式我认为合适的,实现你在找什么:

  1. 您可以在一开始所有的变量,并从那里

  2. 您可以提示编辑您的每一次变量/写一个新的脚本

无论哪种方式,你这样做写出一个批处理文件写另一个批处理文件是愚蠢的,留下的种种潜在代码错误。您不仅会对一个批处理脚本进行错误检查,而且还会有另一个批处理脚本。

因此,这里是你可以做的一些例子:

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 

[email protected] 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. 

在这脚本我们有一种独特的方式来确保每一行都会被写入到新批处理脚本的末尾,但是您还需要记住关键的事情......有时您需要使用^(克拉)以及需要将%%翻倍的时间,以确保两个变量都可以通过,并且在写入新的命令之前,您不会在脚本中触发另一个命令。

+0

你的脚本*方式太长。请将示例缩小到相关的子部分以显示您的答案。你不需要*整个*脚本。此外,请勿将*另一个*答案作为连续发布,这被认为是* noise *,并将被删除。如果你不能把它放到一个答案中,那么这很好地表明你说*太多*。 – casperOne 2012-03-08 14:43:04

+3

我们绝对会*希望*您会有所帮助,但我们也希望每个人都渴望达到有助于*每个人*的质量水平;说,这不是答案是*坏*,但它可以做得更好*我们总是希望SO的用户*使事情变得更好*。看看你的答案,看看*真正需要什么*(而不是代码转储有许多不相关的位)并将其缩小到那个;你会发现它会更好地被接收(以upvotes的形式)。 – casperOne 2012-03-08 15:14:05

+0

另外,请注意“希望这有助于”和您的邮件的签名部分应该被剪辑掉,因为解释[这里](http://stackoverflow.com/faq#signatures)。 – Laf 2012-03-08 15:53:11

1

模板的想法似乎是简单的方法(不确定是否短,但这可能是我将如何接近它。)基于原始创建一个单独的模板,删除所有的SET/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将设置用户的脚本参数,并继续与脚本的其余部分。

+0

不错的想法,但我很困惑,如何循环将工作。 (循环从来不是我的强项。)特别是,它似乎只适用于指定数量的行。如果行数会变化呢? (有些用户配置需要来定义所有的变量,有些没有。)这就是为什么我想它可能会更容易,只需使用''>>把变量末,和'GOTO'跳来跳去所产生的脚本根据需要。 – Iszi 2012-03-08 20:59:25

+0

给我的代码片段(刚刚更新原来的职位),您要求用户进行输入,并根据输入什么命令运行,我可以拼凑一个真实的例子。 – Mechaflash 2012-03-09 20:25:33

+0

完全更改了我的答案。 – Mechaflash 2012-03-12 13:31:44