dos时代菜鸟 发表于 2018-3-10 21:19:01

(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:24:43

本帖最后由 dos时代菜鸟 于 2018-3-10 21:32 编辑

多次调用 diskpart 获取分区 对应的 全部 硬盘及其分区 对应的 数字 和 磁盘分区状况,对所有分区 分配序号,供选择。
当分配 盘符的时候,如果用户输入的 盘符已经在序列内,就提示 重来。


因为要cmd.exe 与 diskpart 间进行数据 变量的 交流,所以要在 cmd 中调用多次 diskpart.探测硬盘分区数据的时候可能会慢一些。

邪恶海盗 发表于 2018-3-10 22:04:09

强势插入,广告位出租...{:1_186:}{:1_186:}{:1_186:}

freesoft00 发表于 2018-3-10 22:10:41

最近很活跃呀。

l3429900 发表于 2018-3-10 23:42:07

谢谢大神,分享有益,学习做一下

dos时代菜鸟 发表于 2018-3-10 23:52:17

又更新

更新 循环,操作完一个 分区,刷新 磁盘序列 信息,继续 处理另一个分区。
考虑到获取 磁盘序列信息 时间比较长,所以 增加了一段代码, 在处理完一个分区以后,不必对 全部硬盘分区序列重新 读取,只要确认 更被操作的 那个分区的信息,并将信息更新到 序列列表。

dos时代菜鸟 发表于 2018-3-10 23:54:47

freesoft00 发表于 2018-3-10 22:10
最近很活跃呀。

呵呵,编编 脚本,活跃下气氛而已。
很久没有 发帖,感觉 老了。

dos时代菜鸟 发表于 2018-3-10 23:59:43

这个脚本 只对应 分区,如果 是那些 系统沉於的 “无主儿” 盘符 可就无法卸掉了。

nttwqz 发表于 2018-3-11 00:11:47

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

freesoft00 发表于 2018-3-11 00:43:52

dos时代菜鸟 发表于 2018-3-10 23:54
呵呵,编编 脚本,活跃下气氛而已。
很久没有 发帖,感觉 老了。

支持。
用dos的大部分岁数都有些了。

dos时代菜鸟 发表于 2018-3-11 08:20:12

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=

dos时代菜鸟 发表于 2018-3-11 09:04:32

把 装卸 合于一个了,看一楼

dos时代菜鸟 发表于 2018-3-11 10:38:03

xp 的 diskpart 的remove没有 dismount 参数,所以只能用在win7。

freesoft00 发表于 2018-3-11 14:03:38

dos时代菜鸟 发表于 2018-3-11 10:38
xp 的 diskpart 的remove没有 dismount 参数,所以只能用在win7。

xp就被考虑了。xp的diskpart命令比较弱,有些参数不支持。

磁盘分区命令,想xp也能用。可以考虑使用win版的gdisk,赛门铁克那个,这个老兄应该驾轻就熟。现在纯dos逐渐的在没落,维护进pe的机会越来越多。

dos时代菜鸟 发表于 2018-3-11 15:22:28

本帖最后由 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盘就可以拔出了。

具体脚本更新,在一楼。

dos时代菜鸟 发表于 2018-3-11 22:03:56

闲着 也是 闲着
继续改进
增加一个计算出 空闲盘符 的 段子,放进去了。挂载 分区 输入盘符的时候 ,进行判断 会更准确。

rengrancunzai 发表于 2018-3-12 08:29:53

谢谢分享

devilma 发表于 2018-3-12 16:31:58

谢谢分享!收藏!

dos时代菜鸟 发表于 2018-3-13 09:33:51

研究改进之:
改进 版本判断方法,否则 10 的 版本会被判定为 1
发现 remove 的 dismount 参数只对有盘符的 分区起作用,改进 就是先 随便分配个盘符,在 卸载。
增加对不能识别硬盘分区的卷 ,比如 光驱,进行处理
不必选择 挂/卸,当要求输入 盘符的时候,如果输入的 是 "0" ,就卸载之。

dos时代菜鸟 发表于 2018-3-13 09:52:33

本帖最后由 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 的使用
考虑英文环境的存在,搜索特定行 用的关键字 不能是中文,


再有问题在改进

dos时代菜鸟 发表于 2018-3-13 14:39:49

diskpart 对 u 盘
select partition 有大部分情况是失效的。但是 detail disk 这个 盘,发现u盘的 partition 已经是焦点了。真是无语 。

lc1212 发表于 2018-4-20 17:45:22

感谢分享,收下备用了。

liguibin 发表于 2018-7-7 14:00:50

谢大神,分享有益
页: [1]
查看完整版本: (2018.03.13)挂载 卸载分区 盘符的 diskpart 脚本