(2018.03.13)挂载 卸载分区 盘符的 diskpart 脚本
本帖最后由 dos时代菜鸟 于 2018-3-13 10:38 编辑增加点儿人气,呵呵,只贴源码,不贴文件,方便讨论,方便更新,不必上传。,需要的,自己复制粘贴成脚本吧。
还是贴个文件,不然不知道 需求量,
脚本小,却有很多思考。
比如
remove 的 dismount 参数的 特点
如何 获取 某文件 某行,第一个单词 和 该行 地n个字符
如何分析 提取 混乱 文本中 特定特点 的 某行内容
如果 用 文本中 上一行的内容 做标记 来 确定本行是 所要数据行
cmd脚本中程序段 call :lable 的使用 和 Exit /b 的使用
考虑英文环境的存在,搜索特定行 用的关键字 不能是中文,
@echo off
setlocal ENABLEDELAYEDEXPANSION
COLOR 0A
mode con: lines=40 cols=120
title 挂/卸载分区
:确定硬盘序列,并生成 罗列分区信息
:top1
echo 正在探测数据........
>%temp%\disk_load.txt echo list vol
>%temp%\dl.txt diskpart /s %temp%\disk_load.txt
call :fresh
:top2
cls
echoDiskpart 挂/卸载分区 Diskpart_Ver:%ver%
echo --------------------------------------------------------------------------------------------
echo Vol盘符 标签 FS 类型 大小 状态 信息
echo---- ----- ------------------------------------------------------
set m=-1
for /f "tokens=*" %%o in (%temp%\part_list.txt) do ( ECHO %%o& set /a m=!m!+1)
echo --------------------------------------------------------------------------------------------
set n=-1
set /p n=请输入待处理卷对应的卷号(Vol):0-!m!,r刷新,x退出:
if /i "!n!"=="x" goto x
if /i "!n!"=="r" goto top1
echo --------------------------------------------------------------------------------------------
call :drv_x& if errorlevel 9 goto top2
call :L & if errorlevel 9 goto top2
echo ------------------------------------------
call :script
))
goto top2
:分配盘符
:L
set d=!drvs:~0,1!
set /p d=请输入一个新盘符,!drvs!默认!drvs:~0,1!,0卸载,9返回,回车确认:
if "!d!"=="9"exit /b 9
if "!d!"=="0"goto l2
:l1
set f=0
for %%c in (%drvs%) do (if /i "%%c"=="!d!" set f=1)
if !f!==0(echo 输入错误,按任意键重新来过... & pause>nul & exit /b 9)
>>%temp%\disk_load.txt echo assign letter=!d!
goto l_ok
:l2
if not "!dm!"=="" ( if"!drv!"==" " ( >>%temp%\disk_load.txt echo assign) )
>>%temp%\disk_load.txt echo remove !dm! noerr
:l_ok
>>%temp%\disk_load.txt echo list vol
echo 正在生载脚本...
exit /b 1
:运行脚本
:script
echo Script (disk_!dx!:!px!):
echo ------------------------------------------
type %temp%\disk_load.txt
echo ------------------------------------------
echo 按任意键开始处理.........
pause>nul
echo 正在运行脚本并刷新数据......
>%temp%\dl.txt diskpart /s %temp%\disk_load.txt
call :fresh
exit /b 1
:检验选取分区是否正确,并生成diskpart基本脚本
:drv_x
echo 正在验证所选^(!n!^),探测对应分区................
set select=
for /f "tokens=*" %%c in (%temp%\part_list.txt) do (
set drv=%%c
set drv=!drv:~6,1!
for /f "tokens=1,*" %%d in ("%%c") do (set q=%%d)
if "!n!"=="!q!" (rem 生成卸载脚本
set select=ok
>%temp%\dx.txt echo select vol !n!
>>%temp%\dx.txt echo list disk
>>%temp%\dx.txt echo list partition
set dx=
set px=
for /f "tokens=1,2,3,*" %%c in ('diskpart /s %temp%\dx.txt') do (
if "%%c"=="*" (if "!dx!"=="" set dx=%%e)
if "%%c"=="*" (if not "!dx!"=="" set px=%%e )
)
if not "!dx!"=="" (if not "!px!"=="" (
>%temp%\disk_load.txt echo select disk !dx!
>>%temp%\disk_load.txt echo select partition !px!
)) else (
echo 无法确定所选卷^(!n!^)对应的硬盘和分区,将直接处理卷.......
>%temp%\disk_load.txt echo select vol !n!
)
exit /b 0
)
)
if not "!select!"=="ok" (
echo 选择错误,按任意键重新选择.....
pause>nul
)
exit /b 9
:fresh
rem 分析 diskpart 脚本运行结果(dl.txt)----整理出硬盘分区序列(part_list.txt)
>%temp%\part_list.txt echo.
set t0=
for /f "tokens=1,*" %%c in (%temp%\dl.txt) do (
set l0=%%c
if "%%c"=="Microsoft" (for /f "tokens=3" %%e in ("%%d") do (set ver=%%e))
if "!l0:~0,1!"=="-" set "t0=ok"
if "!t0!"=="ok" (if not "!l0:~0,1!"=="-" (
if "%%c"=="*" (for /f "tokens=1,*" %%r in ("%%d") do (echo %%s>>%temp%\part_list.txt )
) else (echo %%d>>%temp%\part_list.txt )
))
)
set dm=dismount
for /f "delims=. tokens=1" %%x in ("!ver!") do (if %%x lss 6 set dm=)
call :drv_z
exit /b
:计算出可用盘符
:drv_z
set drvs=
for %%x in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO (
SET F=0
for /f "tokens=2" %%c in (%temp%\part_list.txt) do (IF /i "%%x"=="%%c" set F=1)
if "!f!"=="0"set drvs=%%x,!drvs!
)
echo 可用盘符:!drvs!
exit /b
:结束
:x
本帖最后由 dos时代菜鸟 于 2018-3-10 21:32 编辑
多次调用 diskpart 获取分区 对应的 全部 硬盘及其分区 对应的 数字 和 磁盘分区状况,对所有分区 分配序号,供选择。
当分配 盘符的时候,如果用户输入的 盘符已经在序列内,就提示 重来。
因为要cmd.exe 与 diskpart 间进行数据 变量的 交流,所以要在 cmd 中调用多次 diskpart.探测硬盘分区数据的时候可能会慢一些。
强势插入,广告位出租...{:1_186:}{:1_186:}{:1_186:} 最近很活跃呀。 谢谢大神,分享有益,学习做一下 又更新
更新 循环,操作完一个 分区,刷新 磁盘序列 信息,继续 处理另一个分区。
考虑到获取 磁盘序列信息 时间比较长,所以 增加了一段代码, 在处理完一个分区以后,不必对 全部硬盘分区序列重新 读取,只要确认 更被操作的 那个分区的信息,并将信息更新到 序列列表。
freesoft00 发表于 2018-3-10 22:10
最近很活跃呀。
呵呵,编编 脚本,活跃下气氛而已。
很久没有 发帖,感觉 老了。 这个脚本 只对应 分区,如果 是那些 系统沉於的 “无主儿” 盘符 可就无法卸掉了。
dos时代菜鸟 发表于 2018-3-10 21:24
多次调用 diskpart 获取分区 对应的 全部 硬盘及其分区 对应的 数字 和 磁盘分区状况,对所有分区 分配序号 ...
的确,多次调用diskpart会延长命令执行时间,也不知道有没有什么办法解决。
话说,你这是写着玩的吧,要不然有简单的方法。
@echo off
mode con cols=90
set /p=list vol<nul | diskpart
echo 选择要卸载的卷:
set /p vol=
(echo sel vol %vol% & echo remove) | diskpart
pause dos时代菜鸟 发表于 2018-3-10 23:54
呵呵,编编 脚本,活跃下气氛而已。
很久没有 发帖,感觉 老了。
支持。
用dos的大部分岁数都有些了。 nttwqz 发表于 2018-3-11 00:11
的确,多次调用diskpart会延长命令执行时间,也不知道有没有什么办法解决。
话说,你这是写着玩的吧, ...
其实 挂载也有简单的方法,需要变通一下,用 mountvol 挂载到 目录里面,用完直接删除挂载目录
@echo off && setlocal ENABLEDELAYEDEXPANSION
pushd "%~dp0"
cd /d "%~dp0"
set "p0=%~dp0"
if not ""=="%~1" set "p0=%~1"
if not "!p0:~-1,1!"=="\" set p0=!p0!\
ECHO 联接目录:!P0!
set n=0
for /f "tokens=1 delims= " %%i in ('mountvol /l') do (
set "p=%%i"
if "!p:~1,1!"=="\" set "p1=%%i"
if "%%i"=="***" (
ECHO 待联接卷:!P1!
set "p=!p0!!p1:~12,35!"
if exist "!p!" rd /q "!p!"
mklink /d "!p!" "!p1!">nul
if not !errorlevel! EQU 1 set /a n=!n!+1
)
)
echo 共有 !n! 个卷联接到了 "!p0!"
if !n! gtr 0 (
echo 按任意键将浏览"!p0!" ...&&pause>nul
start explorer.exe "!p0!"
) else (
pause
)
for %%c in (p0 p p1 n) do set %%c=
把 装卸 合于一个了,看一楼 xp 的 diskpart 的remove没有 dismount 参数,所以只能用在win7。 dos时代菜鸟 发表于 2018-3-11 10:38
xp 的 diskpart 的remove没有 dismount 参数,所以只能用在win7。
xp就被考虑了。xp的diskpart命令比较弱,有些参数不支持。
磁盘分区命令,想xp也能用。可以考虑使用win版的gdisk,赛门铁克那个,这个老兄应该驾轻就熟。现在纯dos逐渐的在没落,维护进pe的机会越来越多。 本帖最后由 dos时代菜鸟 于 2018-3-11 15:30 编辑
再次改进,发现 list parttion , detail partiton的方式 不能发现 u盘。
信息搜集 用 list vol
但是发现在
select vol 以后,用 remove 命令有局限,这个 dismount 参数 就有不好用的情况,不能让磁盘分区脱机,所以 还是要用到 select partiton
这就需要 确定 partition 对应的数字,所以 后面 对 某个分区的 装卸 可能要慢一些,但是 脚本运行初期,数据的收集 就 快了。
另外增加了 判断 diskpart 版本 小于 6 的时候,不使用 dismount 参数。
使用 remove 附带 dismount 参数 目的就是可以 直接 卸掉 u盘,然后 u盘就可以拔出了。
具体脚本更新,在一楼。 闲着 也是 闲着
继续改进
增加一个计算出 空闲盘符 的 段子,放进去了。挂载 分区 输入盘符的时候 ,进行判断 会更准确。 谢谢分享 谢谢分享!收藏! 研究改进之:
改进 版本判断方法,否则 10 的 版本会被判定为 1
发现 remove 的 dismount 参数只对有盘符的 分区起作用,改进 就是先 随便分配个盘符,在 卸载。
增加对不能识别硬盘分区的卷 ,比如 光驱,进行处理
不必选择 挂/卸,当要求输入 盘符的时候,如果输入的 是 "0" ,就卸载之。
本帖最后由 dos时代菜鸟 于 2018-3-13 11:53 编辑
还是有问题
那个assign 对于 efi 分区 可以无限次的 分配盘符,就会导致 多个盘符指向一个分区。卸载的时候 就失效了。
看来还要 调整一下,价格判断。
已经改进 ,判断卷是否被分配了盘符
脚本小,却有很多思考。
比如
remove 的 dismount 参数的 特点,
只有 当 确定版本 大于 6.x 包含 dismount 参数,并且 目标卷 已经分配盘符 的情况,用 dismount 才会 使 该卷 脱机,如果是u盘 ,此时就可以拔掉了。
dismount 对于隐藏分区 也是 失效的。比如 efi 分区。
如何 获取 某文件 某行,第一个单词 和 该行 地n个字符
for /f "tokens=*" %%c in (x.txt)
set l=%%c
echo 第六个字符:%l:~5,1%
for /f "tokens=1" %%d in ("%%c") do (
echo 第一个单词:%%d
)
)如何分析 提取 混乱 文本中 特定特点 的 某行内容
如何 用 文本中 上一行的内容 做标记 来 确定本行是 所要数据行
cmd脚本中程序段 call :lable 的使用 和 Exit /b 的使用
考虑英文环境的存在,搜索特定行 用的关键字 不能是中文,
再有问题在改进 diskpart 对 u 盘
select partition 有大部分情况是失效的。但是 detail disk 这个 盘,发现u盘的 partition 已经是焦点了。真是无语 。 感谢分享,收下备用了。 谢大神,分享有益
页:
[1]