Windows 批处理文件:列表目录&;单个变量的文件名,并显示为选择菜单
我在许多不同的windows机器上使用RDP,有时必须将RDP转换成一台,然后再从一台转换到另一台 我想知道是否有可能创建一个批处理文件,该文件可以读取设置路径中所有目录的名称,然后将它们显示为菜单中的编号变量。 输入所选内容后,它将对所选目录中的所有.rdp文件执行相同的操作 下面是一个我如何为每个文件手动硬编码的示例…但是我需要一些能够适应将新rdp文件放到目录中的东西,而不是每次在批处理文件中手动添加它,因为站点/PC的数量和名称可以定期更改Windows 批处理文件:列表目录&;单个变量的文件名,并显示为选择菜单,windows,shell,variables,batch-file,cmd,Windows,Shell,Variables,Batch File,Cmd,我在许多不同的windows机器上使用RDP,有时必须将RDP转换成一台,然后再从一台转换到另一台 我想知道是否有可能创建一个批处理文件,该文件可以读取设置路径中所有目录的名称,然后将它们显示为菜单中的编号变量。 输入所选内容后,它将对所选目录中的所有.rdp文件执行相同的操作 下面是一个我如何为每个文件手动硬编码的示例…但是我需要一些能够适应将新rdp文件放到目录中的东西,而不是每次在批处理文件中手动添加它,因为站点/PC的数量和名称可以定期更改 :site ECHO Location Lis
:site
ECHO Location List
ECHO.
ECHO 1 NSW
ECHO 2 QLD
ECHO.
SET /p site=Enter Selection:
IF "%site%"=="1" GOTO NSW
IF "%site%"=="2" GOTO QLD
:NSW
SET dirname=C:\Machine\NSW\
ECHO Machine List
ECHO.
ECHO 1 Client01.rdp
ECHO 2 Server01.rdp
ECHO 3 Server02.rdp
ECHO.
SET /p machine0=Enter Selection:
IF "%machine0%"=="1" SET machine1=%dirname%Client01.rdp
IF "%machine0%"=="2" SET machine1=%dirname%Server01.rdp
IF "%machine0%"=="3" SET machine1=%dirname%Server02.rdp
GOTO connection
:connection
mstsc %machine1% /console
我发现了几个与此类似的问题(如and),但它们似乎都只是显示一个列表,而不是将它们放入类似菜单的选项中,而且我仍然不完全理解FOR命令是如何工作的
目录结构的示例
C:\Batchfile.bat
C:\Machines\NSW\Client01.rdp
C:\Machines\NSW\Server01.rdp
C:\Machines\NSW\Server02.rdp
C:\Machines\QLD\Client01.rdp
C:\Machines\QLD\Client02.rdp
C:\Machines\QLD\Server01.rdp
基本目录将被设置为C:\Machines,然后batch将每个子目录名称存储到一个编号的变量中,并将它们回显到屏幕上并提示选择
Location List
1 NSW
2 QLD
Enter Selection:_
Machine List for NSW
1 Client01.rdp
2 Server01.rdp
3 Server02.rdp
Enter Selection:_
如果用户输入1,那么它会将QLD子目录中的每个.RDP文件名存储到一个编号的变量中,并将它们回显到屏幕上并提示选择
Location List
1 NSW
2 QLD
Enter Selection:_
Machine List for NSW
1 Client01.rdp
2 Server01.rdp
3 Server02.rdp
Enter Selection:_
在用户此时进行选择后,我希望使用所选的.rdp文件和mstsc命令来启动到所选计算机的rdp会话,然后循环返回开始,以允许同时打开第二个连接
如果您能提供任何帮助,我将不胜感激。这里有一种方法:
@echo off
setlocal enabledelayedexpansion
:Start
ECHO Location List
ECHO.
ECHO NSW
ECHO QLD
ECHO.
SET /p site=Enter Selection:
for /f %%a in ('dir /b/s "c:\Temp\%site%\*.rdp"') do (
set /a i+=1
echo !i! - %%~nxa
set mach[!i!]=%%~nxa
)
set /p m0=Enter Selection:
echo mstsc !mach[%m0%]! /console
set /p sel=Would you like to launch another [y/n]?
if /i "%sel%" EQU "y" Goto :start
或
另外,这是假设您的所有服务器都是2003。从2008年开始,我相信/console已经取代了/admin。如果是这样的话,根据您所连接的服务器的版本,很容易添加更多的逻辑 这里有一种方法:
@echo off
setlocal enabledelayedexpansion
:Start
ECHO Location List
ECHO.
ECHO NSW
ECHO QLD
ECHO.
SET /p site=Enter Selection:
for /f %%a in ('dir /b/s "c:\Temp\%site%\*.rdp"') do (
set /a i+=1
echo !i! - %%~nxa
set mach[!i!]=%%~nxa
)
set /p m0=Enter Selection:
echo mstsc !mach[%m0%]! /console
set /p sel=Would you like to launch another [y/n]?
if /i "%sel%" EQU "y" Goto :start
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /f "delims==" %%i IN ('SET s_ 2^>nul') DO SET "%%i="
SET "sourcedir=c:\sourcedir"
FOR /f "delims=" %%a IN ('dir/s/b/a-d "%sourcedir%\*.rdp"') DO (
SET s_=%%~dpa
FOR /f %%b IN ("!s_:~0,-1!") DO SET s_#%%~nb=Y&SET s_@%%~nb_%%~na=Y
)
CALL :showmenu "Location List" #
IF /i "%s_%"=="q" GOTO :EOF
SET s_site=%s_%
CALL :showmenu "Machine List for %s_site%" @ %s_site%
IF /i "%s_%"=="q" GOTO :EOF
SET s_machine=%s_%
ECHO(==============
ECHO site=%s_site% machine=%s_machine%
GOTO :EOF
:showmenu
SET s_items=1
CLS
ECHO(%~1
ECHO(
FOR /f "tokens=2,3delims=_%2=" %%i IN ('set s_%2') DO (
IF "%3"=="" (
CALL :showline %%i
) ELSE (
IF "%3"=="%%i" CALL :showline %%j
)
)
ECHO(
SET "s_="
SET /p "s_=Enter Selection : "
IF NOT DEFINED s_ SET s_=Q
IF /i "%s_%"=="q" GOTO :EOF
IF DEFINED s_%s_% CALL SET s_=%%s_%s_%%%&GOTO :EOF
GOTO showmenu
:showline
SET "s_= %s_items%. "
ECHO %s_:~-4%%1
SET s_%s_items%=%1
SET /a s_items+=1
SET "s_%s_items%="
GOTO :eof
或
另外,这是假设您的所有服务器都是2003。从2008年开始,我相信/console已经取代了/admin。如果是这样的话,根据您所连接的服务器的版本,很容易添加更多的逻辑
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /f "delims==" %%i IN ('SET s_ 2^>nul') DO SET "%%i="
SET "sourcedir=c:\sourcedir"
FOR /f "delims=" %%a IN ('dir/s/b/a-d "%sourcedir%\*.rdp"') DO (
SET s_=%%~dpa
FOR /f %%b IN ("!s_:~0,-1!") DO SET s_#%%~nb=Y&SET s_@%%~nb_%%~na=Y
)
CALL :showmenu "Location List" #
IF /i "%s_%"=="q" GOTO :EOF
SET s_site=%s_%
CALL :showmenu "Machine List for %s_site%" @ %s_site%
IF /i "%s_%"=="q" GOTO :EOF
SET s_machine=%s_%
ECHO(==============
ECHO site=%s_site% machine=%s_machine%
GOTO :EOF
:showmenu
SET s_items=1
CLS
ECHO(%~1
ECHO(
FOR /f "tokens=2,3delims=_%2=" %%i IN ('set s_%2') DO (
IF "%3"=="" (
CALL :showline %%i
) ELSE (
IF "%3"=="%%i" CALL :showline %%j
)
)
ECHO(
SET "s_="
SET /p "s_=Enter Selection : "
IF NOT DEFINED s_ SET s_=Q
IF /i "%s_%"=="q" GOTO :EOF
IF DEFINED s_%s_% CALL SET s_=%%s_%s_%%%&GOTO :EOF
GOTO showmenu
:showline
SET "s_= %s_items%. "
ECHO %s_:~-4%%1
SET s_%s_items%=%1
SET /a s_items+=1
SET "s_%s_items%="
GOTO :eof
这种方式是自我调节的。不幸的是,它也使用了一些象形文字
第一步是确保从环境中删除名称以s\uu
开头的所有变量。对s\uu
没有什么特别的意义-这正是我选择的。如果存在s_…
变量,则set s_
的输出形式为s_whatever=something
。如果不存在,则2>nul
会抑制错误消息,但需要用插入符号(^)对>进行转义,以告知cmd
重定向是要执行的命令的一部分,而不是for
命令的一部分。如果s_whatever=something
,则/f的将使用=作为分隔符解析该行,从而将s_whatever
分配给指定的元变量%%i
下一步是查找从源目录开始的所有.RDP
文件名dir/s/b/a-d
生成完整文件名的空行(无页眉或页脚),抑制与指定掩码匹配的任何目录名
整个文件名被分配给%%a
,因为delims=”“
即没有分隔符S\uuu
用作通用变量,并在%%a
中分配文件名的驱动器和路径部分。然后删除s\uuu
的最后一个字符(它将是a\),并且/f%%b
的将结果字符串解释为一个文件名。然后设置变量s#site
和s_@site_machine
(设置为Y,但可以设置为任何值)
注意的用法!s:~0,-1
指定将运行时值的字符0..last-1作为s
-的值!指定SETLOCAL ENABLEDELAYEDEXPANSION
处于活动状态时的运行时值
主例程的其余部分只需使用各种参数调用两次SHOWMENU
,并将s
中返回的值分配给相应的变量
SHOWMENU
将项目数(s_items
)设置为比可用项目数多1,清除屏幕并从第一个子例程参数(%1
)显示菜单标题-但引号被抑制(%1
)-这允许参数包含空格
下面的FOR/F
标记了s#
(站点名称)或s@
(站点+机器名称)的SET
列表。使用分隔符u和=以及#或@意味着对于像s_35;NSW=Y
这样的行,将NSW
分配给%i
,而像s_@NSW\Server01=Y
这样的行将NSW
分配给%i
和Server01
分配给%j
选择适当的零件并将其传递给SHOWLINE例程
s
然后用于用户输入。强制清除意味着如果用户只按ENTER键,它将保持未设置状态,否则它将保留其原始值
我已经任意分配了一个Q
输入来退出,如果没有用户输入,那么也会退出。否则,如果设置了变量s_choicemade
,则将s_
设置为该值,并从子例程返回到达EOF
。如果做出无效选择,则不会设置s_invalidchoice
,因此将重新显示菜单
SHOWLINE
过程将s_
设置为空格lineNumber.space,然后显示参数(%1
),前面是最后4个字符