dos时代菜鸟 发表于 2018-4-22 22:56:12

vbs 调用 diskpart 交互式 装卸 硬盘分区盘符

本帖最后由 dos时代菜鸟 于 2018-4-28 15:36 编辑


仅 在 win10x64 环境测试通过,其他环境 暂时 未测试。脚本已经尽量避免涉及对中文信息的提取,估计 英文下也能用。

比 cmd 优势在于不必频繁 调用 Diskpart.exe 节省调取时间。
因为是 内存 运行,不需要生成临时文件,diskpart 也是已经运行了的,所以 ,可以对 脚本所在分区进行 卸载。

算是 给 dos 板块 赚点儿人气儿吧。呵呵。



On error resume next

hide_cmd '调用隐藏运行代码

set ws=createObject("wscript.shell")
Set diskpart = ws.Exec("diskpart.exe")

DIM DISK
vol_line2=fresh()
wscript.echo vol_line2
volx2=volx()

with diskpart
x=""
do until x=false
    x=inputbox("盘 卷   盘符   大小格式   卷标"&chr(10)&_
                "------------------------------------"&chr(10)&_
                vol_line2&chr(10)&_
                "请输入一个卷对应的序号:("&word(vol_line2,2)&"...)","选择装/卸一个卷")
    ln=0
    find=0
    for each v in split(word(vol_line2,2),",")
      ln=ln+1
      if v<>""and v=x then
      find=1
      if vol_d(vol_line2,ln)=" " then
            wscript.echo "需要挂载"
            wscript.echo volx2
                y=""
                y=inputbox("盘 卷   盘符   大小格式   卷标"&chr(10)&_
                "------------------------------------"&chr(10)&_
                vol_line2&chr(10)&_
                "请输入一个盘符:"&chr(10)&_
                "卷: "&v&" --> "&volx2,"输入一个盘符")
                find2=0
                for each v2 in split(volx2,",")
                  if v2<>"" and v2=Ucase(y) then
                      .StdIn.WriteLine "select vol "&v
                      .StdIn.WriteLine "Assign Letter="&v2
                      wscript.echo list1(1,2)
                      find2=1
                      exit for
                  end if
                next
                if find2=0 then msgbox "输入错误!"
      else
            wscript.echo "需要卸载"
            .StdIn.WriteLine "select vol "&v
            .StdIn.WriteLine "remove "
            wscript.echo list1(1,2)
      end if
      vol_line2=fresh()
      volx2=volx()
      exit for
      end if
    next
    if x<>"" and find=0 then msgbox "输入错误!"
loop
.StdIn.WriteLine "exit"
Do Until .Status=1
    wscript.sleep 100
Loop
End with

'-------------获取卷序列列表
function fresh()
with diskpart
.StdIn.WriteLine "list disk"
fresh=""
for each d in split(word(line0(list1(1,1)) , 2 ),",")
    if d<>""then
      .StdIn.WriteLine "select disk "&d
      .StdIn.WriteLine "detail disk"
      DISK=D
      fresh=fresh&vline(wordl(line0(list1(2,1)),2))
    end if
next
end with
End function

'-------------获取未使用的盘符列表
function volx()
with diskpart
volx="C,D,E,F,G,H,I,J,K,L,N,M,O,P,Q,R,S,T,U,V,W,X,Y,Z"
.StdIn.WriteLine "list vol"
for each d in split(word0(wordl(line0(list1(1,1)),2) , 7,1 ),",")
    if d<>" " and d<>"" then
      volx=replace(volx,d&",","")
    end if
next
end with
End function


'----------找出所选卷的盘符
Function vol_d(lx,lv)
vol_d=""
l=""
ln2=0
for n=1 to len(lx)
if mid(lx,n,1)=chr(10) and l<>chr(10) then
      ln2=ln2+1
      if ln2=lv thenvol_d=mid(l,11,1)
      l=""
else
    l=l&mid(lx,n,1)
end if
next
End function

'----------根据 卷列表信息流 整理出 整理出 带有磁盘编号的 卷信息流-----------
Function vline(lx)
vline=""
l=""
for n=1 to len(lx)
if mid(lx,n,1)=chr(10) and l<>chr(10) then
      vline=vline&" "&DISK&""&mid(l,1,7)&mid(l,41,9)&" "&mid(l,24,7)&mid(l,11,13)&chr(10)
      l=""
else
    l=l&mid(lx,n,1)
end if
next
End function

'------------获取某个字符流中各行的某个范围(r~s)的字符串
Function word0( lx , r ,s)
word0=""
l=""
for n=1 to len(lx)
if mid(lx,n,1)=chr(10) and l<>chr(10) then
      word0=word0&mid(l,r,s)&","
      l=""
else
    l=l&mid(lx,n,1)
end if
next
End function

'-------------获取文本流中 各行第r个单词及其后内容---
Function wordl(lx,r)
wordl=""
l=""
for n=1 to len(lx)
if mid(lx,n,1)=chr(10) and l<>chr(10) then
       i=0
       s=0
      for x=1 to len(l)
      if mid(l,x,1)<>" " then
          if s=0 then i=i+1
          s=1
          if i=r then
            wordl=wordl&mid(l,x)&chr(10)
            exit for
          end if
      else
          s=0
      end if
      next
      l=""
else
    l=l&mid(lx,n,1)
end if
next
End function

'------------获取某个字符流中各行的某个单词,组合成一个由","隔断的字符串
Function word( lx , r)
word=""
l=""
for n=1 to len(lx)
if mid(lx,n,1)=chr(10) and l<>chr(10) then
      parts=split(l)
      ps=0
      for each p in parts
          if p<>"" then
            ps=ps+1
            if ps=r thenword=word&p&","
          end if
      next
      l=""
else
    l=l&mid(lx,n,1)
end if
next
End function

'------------获取某个字符流中有价值的各行---标记字符"-"-----------
Function line0(lx)
line0=""
l=""
s=0
for n=1 to len(lx)
if mid(lx,n,1)=chr(10) and l<>chr(10) then
      if left(l,1)="-" then s=1
      if s=1 and left(l,1)<>"-" then
      if left(l,1)="*" then l=mid(l,3)
      line0=line0&l&chr(10)
      end if
      l=""
else
    l=l&mid(lx,n,1)
end if
next
End function

'返回 diskpart.stdout 字符指针位置开始计算,第m条命令及其后面的n条命令的输出结果
function list1(m,n)
list1=""
      with diskpart
         .stdin.WriteLine "rem "
                i=0
                Do While i<(m+n)
                  strFromProc=replace(replace(trim(.StdOut.ReadLine()),chr(10),""),chr(13),"")&chr(10)
                  if instr(1,strFromProc,">")>0 then
          i=i+1
                  elseif i>(m-1) and strfromproc<>chr(10)then
                      list1=list1&strfromproc
      end if
                Loop
      end with
end function

'----------------隐藏运行代码-----------------------
Sub hide_cmd()
set ws=createObject("wscript.shell")
hide= """" & WScript.scriptFullName& """"
if WScript.Arguments.count=0then
    ws.run "cscript.exe " & hide &"-hide " ,0,false
    WScript.quit
elseif WScript.Arguments(WScript.Arguments.count-1)<>"-hide" then
    args=" "
    for each arg in WScript.Arguments
      args=args&""& """" & arg & """"
    next
    ws.run "cscript.exe " & hide &args &"-hide " ,0,false
    WScript.quit
end if
end Sub
'-----------------隐藏代码结束----------------------

dos时代菜鸟 发表于 2018-4-22 22:57:36

本帖最后由 dos时代菜鸟 于 2018-4-23 10:34 编辑

{:1_186:}

脚本 利用 exec 的 stdout 获取 diskpart 命令运行结果 ,分析 硬盘分区序列,由用户 选择 分区卷 序号,完成操作。
如果 选择的卷 有 盘符,就卸载,如果没有盘符,就询问 分配一个盘符。

脚本运行中间 不生成任何 中间文件,就一个 vbs 脚本 。

比 cmd 优势在于不必频繁 调用 Diskpart.exe 节省调取时间。

需要 系统 vbs 支持,有 diskpart.exe

可能 用vbs 调用系统dll 实现这个 功能 更便捷,这里只是 一个 实验 样本而已,就是 想 看看exec 的 stdout 获取 程序输出 结果方面 的 功能 和应用。


q8155128 发表于 2018-4-23 08:41:13

嘻嘻......

大师又放毒了......

每次看见大师的毒.......

俺的心里就特别的高兴......

{:1_192:}

a22124497 发表于 2018-4-23 08:56:14

批处理呀,VBS之类的都不太行了,以后估计都得玩POWERSHELL了吧

dos时代菜鸟 发表于 2018-4-23 09:27:04

a22124497 发表于 2018-4-23 08:56
批处理呀,VBS之类的都不太行了,以后估计都得玩POWERSHELL了吧

powershell 对环境要求可能更加苛刻,
pe下,还是 cmd 最稳妥。

dos时代菜鸟 发表于 2018-4-23 09:57:40

本帖最后由 dos时代菜鸟 于 2018-4-23 10:38 编辑

加了个 获取 文本流 各行 第n个单词及其后面内容的函数。这个 在 cmd 下,一个 for 就搞定了。vbs 下 对文本流的操作,具体功能 都需要 自己编,正好 复习一下 vbs 下的文本字符串操作。呵呵。

用 vbs 的 Exec 方式 ,还有一个好处就是 可以一次调用 Disk part 完成所有操纵,不用像 cmd 中那样 频繁 调用 diskpart.exe 。

双响炮 发表于 2018-5-13 15:51:13

特别喜欢这种代码式的教学帖,比起纯软件的帖子更容易学习到东西
页: [1]
查看完整版本: vbs 调用 diskpart 交互式 装卸 硬盘分区盘符