无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
查看: 52646|回复: 139
打印 上一主题 下一主题

[原创]DOS下实现硬盘自动无损数据重新分区的方法

[复制链接]
跳转到指定楼层
1#
发表于 2004-3-15 22:28:09 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
[这个贴子最后由Climbing在 2004/03/17 02:58pm 第 2 次编辑]

[原创]DOS下实现硬盘自动无损数据重新分区的方法
================
一、问题的提出
================
说起给硬盘分区,有经验的用户都不会陌生,而且是属于计算机系统安装和维护中经常做的一种操作。当然,分区软件有很多,经典的FDISK,权威的PQ PartitionMagic(也就是大名鼎鼎的“分区魔术师”了,下面简称PM) 或者Acronis PartitionExpert(分区软件的新秀),还有命令行下的Gdisk,当然,还有Diskman、FBDisk等很多软件,个人经常使用的是PQ Partition Magic、BootStar,当然也经常使用Fdisk做一些辅助性的操作。DOS方式下人工交互式的分区个人认为还是PM最好用,如果要自动进行分区,对于全新的硬盘来说,当然用Gdisk是一个不错的选择。但如果我想在DOS下使用命令行实现类似PM的无损数据分区该如何办呢?例如,我想实现自动安装IBM一键恢复,这个方案要解决的第一个问题就是如何实现自动无损数据分区(在硬盘的末尾自动建立一个指定大小的主分区并设置合适的卷标)。
==================
二、问题解决过程
==================
要解决前面提出的问题,首选当然就是考虑PM是否有这个功能了,如果PM能够支持在命令行运行一个类似批处理的自动分区脚本文件,这个问题就可以解决了。我日常使用的是从网上下载的PM 8.0纯DOS版,在DOS方式下输入:
pqmagic /?
还真有不少参数,但仔细一看,没有一个参数能够完成前面所述功能。看来PM不成,于是用google在网上搜索,搜索到最多的结果就是gdisk,但可惜它只能在硬盘上有未分区空间的前提下才可以使用,找不到软件怎么办?灵机一动,访问PowerQuest的官方网站,在该网站首页看到的第一个消息就是PowerQuest公司被Symantec公司收购了,网页上方打上了大大的Symantec的字样标志,好在网站还在正常运行,正常的技术支持页面也可以使用,于是试着搜索"Batch"或者"Script"之类的关键字,果然在知识库中找到了有关运行Script时出现的错误及解决办法等,后来发现这些错误只是针对Partition Magic Pro(下面简称为PM Pro) 或者Volume Manager这样的软件,Volume Manager不用考虑了,那是Server系统使用的分区软件,于是打开PM Pro的介绍页面(点击访问),发现官方网站上Pro版本的PM最新版本是7.0,在其功能介绍中的“EXCEPTIONAL EASE OF USE” 中发现这一段介绍“ Scripting - Change the partitions on a computer by running a script that you create with ScriptBuilder. To run a script, simply pass the script filename to the program on the command line. ”,好了,这就是我们要找的东西了,原来普通的PM并不支持脚本操作,只有Pro版本才支持,于是又到网上搜索并向各个论坛求助,终于在“中国DOS联盟之联合DOS论坛(点击访问)”的walu站友那里取得了PM Pro 7.0的纯DOS版本(稍后会提供软件的下载),也巧了,这个问题的缘起也是因为该论坛里mewf网友的一个求助帖子:“如何实现用dos程序自动调整分区大小?(点击访问)”,不由得让人发出“问题由哪里开始就由哪里结束”的感叹。
==================
三、问题的解决
==================
有了适当的工具再加上详细的参考文档,问题当然就迎刃而解了,下面给出我的初步成果,下面的脚本例子就是为了实现这样一个目标:在硬盘最后面腾出2G的空间并在其上建立一个FAT32主分区,分区卷标为“SYS_GHOST”。
开始我先按照标准的方法书写了一个脚本,但在调试过程中(建议在PM Pro For Windows版本上使用内置的ScriptBuilder进行脚本的书写和调试)发现书写的脚本有一个命令无法执行,但个人感觉命令并没有写错(到现在原因仍然未明),只好修改脚本使用另一种笨办法来实现,这样就有了V1、V2两个版本的脚本,V1版本中不能执行的那条命令我已经标出,还希望大家共同研究,找出不能执行的原因。个人感觉V1版本要比V2版本写的漂亮,可惜不能用。
下面是有关文件的下载:
1、PowerQuest Partition Magic Pro 7.0 For DOS(866KB,点击下载)
2、PowerQuest PartitionMagic Pro脚本设计参考文档(PDF格式英文文档,205KB,点击下载)
3、在硬盘最后面自动创建指定大小的主分区脚本V1(运行时出错,但脚本写的自认没有问题,请高手们共同研究)
4、在硬盘最后面自动创建指定大小的主分区脚本V2(运行正常,但没有脚本1中的程序完美,凑和着用吧)
5、自动在第一块硬盘最后创建一键恢复用主分区的脚本(这算是第三个版本,经过初步测试,运行基本正常,但需要进一步测试,5KB)

上述书写的脚本中都写了详尽的注释,请使用时自己根据实际情况修改里面的参数。
脚本的执行用法(假设脚本文件名为PQ.PQS,且在当前目录下):
pqmagic /cmd=pq.pqs [/dbg=debug.txt] [/log=log.txt]
[]中的内容为可选参数,可以用来调试和检查脚本执行过程中出现的问题:
/dbg:调试文件
/log:执行日志文件

===============
V1脚本内容:
// ****************************************************************************************************************
// CreatePrimaryPartitionAtDiskEnd.PQS:在第一块硬盘的最后建立指定大小的主分区
// 运行前提:
//   1、硬盘最后面一个分区(一般是扩展分区的最后一个逻辑盘)有足够的空闲空间(包括后面的未分配空间)有满足需要的空间。
//   2、硬盘上所有的主分区加扩展分区数量不能大于3。
// 脚本创建者:Climbing(QQ:653668, Email:xclimbing@msn.com, Homepage:http://www.nufans.net/dvbbs)
// 创建日期:2004.03.15
// 目前本脚本运行状态:不能正常运行,在运行到第56行时出错,原因未明
// ****************************************************************************************************************
// 设置你要创建的主分区的大小,单位为MB(默认是2048MB,即2G)。
Dim PriSize
PriSize = 2048
//默认情况下不检测坏扇区,提高操作速度
Set Default Bad Sector Test State OFF
// 选择第一块硬盘
Select Disk 1
// 检测当前硬盘上的主分区数量
Dim PriNum
Dim i
i = 1
PriNum = 0
Select Partition FIRST
DO WHILE i < GetTotalPartitions
     IF IsPrimary Then
          PriNum = PriNum + 1
     End If
     Select Partition Next
     i = i + 1
Loop
IF IsPrimary Then
     PriNum = PriNum + 1
End If
// 检测硬盘上是否有扩展分区,如果有,也算是一个主分区
dim ExtNum
ExtNum = GetPartitionNumber Extended
If  ExtNum <> 0 Then
     PriNum = PriNum + 1
End If
// 只有主分区数量小于4才可以继续
IF PriNum < 4 Then
     //选择最后一个分区
     Select Partition Last
     // 检测最后一个分区后面的剩余空间
     Dim LastFreeNum
// 注意:在运行下面加粗的这一行命令时会出错,错误提示是该命令无法完成。
// 英文提示:[Script error(53)]: Unable to complete command:
// 这个命令的作用应该是返回硬盘最后一个分区后面的未分配空间的编号,如果没有,则返回0
     LastFreeNum = GetUnallocatedNumber After Selected Partition

     Dim NeedSpace
     NeedSpace = PriSize
     Dim bTrun
     bTrun = 1
     IF LastFreeNum <> 0 Then
     // 选中硬盘最后的未分配空间并检测其大小是否满足需要,如果不满足,则需要缩小最后一个分区的大小
          Select Unallocated LastFreeNum
          If GetSelectedUnallocatedSize < PriSize then
               NeedSpace = PriSize - GetSelectedUnallocatedSize
          Else
               bTrun = 0
          End If
     End If
     Select Partition Last
     Dim bQuit
     bQuit = 0
     If bTrun = 1 Then
          // 检测该分区未使用空间是否满足要求
          IF GetUnusedAmount >= NeedSpace Then
               //改变最后一个分区的大小,在其后面空出需要大小的空间(即NeedSpace变量保存的值)
               Resize Space After NeedSpace
          Else
               bQuit = 1
          End If
     End If
     If bQuit = 0 Then
          //选中最后的未分配空间(刚才空出的)
          Select Unallocated After Selected Partition
          //在硬盘最后创建指定大小的分区,分区卷标为SYS_GHOST,当然,你可以根据实际情况修改卷标。
          Create /FS=FAT32 /LABEL="SYS_GHOST" /Size=PriSize /Position=END
          // 将这个分区转换为主分区
          Convert To Primary
     End If
End IF

版本2脚本内容:
// ****************************************************************************************************************
// CreatePrimaryPartitionAtDiskEnd.PQS:在第一块硬盘的最后建立指定大小的主分区
// 运行前提:
//   1、硬盘最后面一个分区(一般是扩展分区的最后一个逻辑盘)有足够的空闲空间(包括后面的未分配空间)有满足需要的空间。
//   2、硬盘上所有的主分区加扩展分区数量不能大于3。
// 脚本创建者:Climbing(QQ:653668, Email:xclimbing@msn.com, Homepage:http://www.nufans.net/dvbbs)
// 创建日期:2004.03.15
// 目前本脚本运行状态:正常
// ****************************************************************************************************************
// 设置你要创建的主分区的大小,单位为MB(默认是2048MB,即2G)。
Dim PriSize
PriSize = 2048
//默认情况下不检测坏扇区,提高操作速度
Set Default Bad Sector Test State OFF
// 选择第一块硬盘
Select Disk 1
// 检测当前硬盘上的主分区数量
Dim PriNum
Dim i
i = 1
PriNum = 0
Select Partition FIRST
DO WHILE i < GetTotalPartitions
     IF IsPrimary Then
          PriNum = PriNum + 1
     End If
     Select Partition Next
     i = i + 1
Loop
IF IsPrimary Then
     PriNum = PriNum + 1
End If
// 检测硬盘上是否有扩展分区,如果有,也算是一个主分区
dim ExtNum
ExtNum = GetPartitionNumber Extended
If  ExtNum <> 0 Then
     PriNum = PriNum + 1
End If
// 只有主分区数量小于4才可以继续
IF PriNum < 4 Then
     //选择最后一个分区,并将其扩大到占用后面所有的未分配空间(开始绕弯子了)
     Select Partition Last
     Resize Larger Max
     
     // 检测该分区未使用空间是否满足要求
     Dim bQuit
     bQuit = 0
     IF GetUnusedAmount >= PriSize Then
          //改变最后一个分区的大小,在其后面空出需要大小的空间(即前面PriSize变量保存的值)
          Resize Space After PriSize
     Else
          bQuit = 1
     End If
     
     If bQuit = 0 Then
          //选中最后的未分配空间(刚才空出的)
          Select Unallocated After Selected Partition
          //在硬盘最后创建指定大小的分区,分区卷标为SYS_GHOST,当然,你可以根据实际情况修改卷标。
          Create /FS=FAT32 /LABEL="SYS_GHOST"
          // 将这个分区转换为主分区
          Convert To Primary
     End If
End IF
在脚本2中,如果最后一个分区后面有未分配空间,那么我先将最后一个分区扩大占满未分配空间,然后将将它缩小腾出需要的空间,这样中间就绕了一个弯,可能会导致操作过程大幅度延长(例如你最后一个分区中存放的数据较多的话),当然,如果最后一个分区没有多少数据,应该不会太影响执行速度的。
呵呵,第三个版本的脚本出来了,可费了我不少心思,不过还需要大家进一步测试。
第三个版本充分考虑了各种硬盘的情况,因此搞的也就比较复杂,估计肯定有Bug存在,我已经测试了几种情况,但有些极限情况没有测试。
版本3脚本的下载链接:
自动在第一块硬盘最后创建一键恢复用主分区的脚本(经过初步测试,需要进一步测试,5KB)
下面是脚本内容:
// ****************************************************************************************************************
// F11_AutoCreatePartition.PQS:在第一块硬盘的最后建立第一个分区使用空间的1/2 + 200MB大小的主分区
// 本脚本的设计目标是适应各种情况的硬盘。
// 脚本创建者:Climbing(QQ:653668, Email:xclimbing@msn.com, Homepage:http://www.nufans.net/dvbbs)
// 创建日期:2004.03.17
// 目前本脚本运行状态:初步测试运行正常,但没有运行各种极限情况下的测试,因此需要进一步测试
// ****************************************************************************************************************
// 允许用户在操作后手工重新启动计算机,否则将自动重新启动计算机
Allow Manual Reboot
//默认情况下不检测坏扇区,提高操作速度
Set Default Bad Sector Test State OFF
// 选择第一块硬盘
Select Disk 1
//选择第一个分区
Select Partition First
Dim PriSize
// 检测第一个分区的使用空间,将PriSize设置成其使用空间的1/2再加上200M,否则恐怕不够用
PriSize = GetUsedAmount / 2 + 200
// 检测当前硬盘上的主分区数量
Dim PriNum
Dim i
i = 1
PriNum = 0
Select Partition FIRST
DO WHILE i < GetTotalPartitions
     IF IsPrimary Then
          PriNum = PriNum + 1
     End If
     Select Partition Next
     i = i + 1
Loop
IF IsPrimary Then
     PriNum = PriNum + 1
End If
// 检测硬盘上是否有扩展分区,如果有,也算是一个主分区
dim ExtNum
ExtNum = GetPartitionNumber Extended
If  ExtNum <> 0 Then
     PriNum = PriNum + 1
End If
// 只有主分区数量小于4才可以继续
IF PriNum < 4 Then
     // 如果存在扩展分区,则选择扩展分区,让它占满前后所有的未分配空间
     If ExtNum <> 0 Then
          Select Disk 1
          Select Partition Extended
          Resize Max
     End if
     // dOperPnum用来保存操作过多少分区
     Dim dOperPnum
     dOperPnum = 0
     // bMove 用来判断是否进行了空间腾出操作,如果是,刚为后面的空间移动提供判断基础
     Dim bMove
     bMove = 0
     // dLastOpPar保存最后一次操作的分区编号
     Dim dLastOpPar
     // 如果当前未分配空间数量已经满足需要,将不需要进行重新分配空间操作
     If GetTotalUnallocatedSpaces < PriSize Then

          //选择最后一个分区并判断其是否为主分区
          Select Partition Last
          Check
          // FreeSpace用来保存已经腾出的空间
          Dim FreeSpace
          FreeSpace = 0
          // NeedSpace用来保存还需要腾出多少空间
          Dim NeedSpace
          NeedSpace = PriSize
          Dim dTmp
          dTmp = 0
          // 从最后一个分区循环往前操作以腾出需要的空间
          i = 0
          Do While FreeSpace < PriSize  
               // 将当前操作分区扩到最大
               Resize Larger Max
               // 检测该分区未使用空间是否满足要求,如果满足,空出需要空间,如果不满足,继续操作
               IF GetUnusedAmount >= NeedSpace Then
                    //改变该分区的大小,在其后面空出需要大小的空间(即NeedSpace变量保存的值)
                    Resize Space After NeedSpace
                    FreeSpace = FreeSpace + NeedSpace
                    bMove = 1
               Else
                    // 如果本分区剩余空间大于100M,则将本分区缩小未使用空间减100M的大小
                    If GetUnusedAmount > 100 Then
                         dTmp = GetUnusedAmount - 100
                         Resize Space After dTmp
                         FreeSpace = FreeSpace + dTmp
                         NeedSpace = PriSize - FreeSpace
                         bMove = 1
                    End If
               End If
               i = i + 1
               dOperPnum = dOperPnum + 1
               // 如果循环到了第一个分区但空间仍然不足,则直接退出循环
               If i < GetTotalPartitions Then
                    Select Partition Previous
                    Check
                    dLastOpPar = GetPartitionNumber Next
               Else If FreeSpace < PriSize Then
                    dLastOpPar = GetPartitionNumber First
                    Exit Loop
               End If
          Loop
     End If
     // 如果没有进行分区分割操作,两个原因:1、磁盘空间不足;2、未分配空间已经够用
     If bMove = 0 Then
          dLastOpPar = GetPartitionNumber First
          dOperPnum = GetTotalPartitions
          Select Partition First
          Move Left Max
     Else               
          // 开始将前一个循环中腾出的空间进行后移操作
          Dim LastMoveParType
          Dim CurParNum
          i = 1
          If bMove = 1 Then
               Select Disk 1
               Select Partition dLastOpPar
               CurParNum = GetPartitionNumber Next
               If IsPrimary Then
                    LastMoveParType = 1
               Else
                    LastMoveParType = 0
               End If
               Do While i < dOperPnum
                    Select Partition Next
                    If IsPrimary Then
                         If LastMoveParType = 0 Then
                              Select Disk 1
                              Select Partition Extended
                              Resize Min
                         End If
                    Else
                         If LastMoveParType = 1 Then
                              Select Disk 1
                              Select Partition Extended
                              Resize Left Boundary Max
                         End If
                    End If
                    Select Partition CurParNum
                    Move Left Max
                    If IsPrimary Then
                         LastMoveParType = 1
                    Else
                         LastMoveParType = 0
                    End If
                    CurParNum = GetPartitionNumber Next
                    i = i + 1
               Loop
               // 选中最后的未分配空间(刚才空出的)
               Select Unallocated After Selected Partition
               //在硬盘最后创建指定大小的分区,分区卷标为SYS_GHOST,当然,你可以根据实际情况修改卷标。
               Create /FS=FAT32 /LABEL="SYS_GHOST"
               // 将这个分区转换为主分区
               Convert To Primary
          End If
     End If
End If

[ 本帖最后由 老毛桃 于 2006-7-19 03:51 PM 编辑 ]

评分

参与人数 1无忧币 +10 收起 理由
haiou327 + 10 精品文章

查看全部评分

141#
发表于 2012-3-24 21:42:16 | 只看该作者
希望多出这样的强帖啊。5555555
回复

使用道具 举报

140#
发表于 2011-6-25 12:23:05 | 只看该作者
顶一下经典的东西。
回复

使用道具 举报

139#
发表于 2011-6-24 17:34:11 | 只看该作者
感谢帮主不吝分享源码!!
回复

使用道具 举报

138#
发表于 2011-3-3 15:26:00 | 只看该作者
[原创]DOS下实现硬盘自动无损数据重新分区的方法


佩服楼主
回复

使用道具 举报

137#
发表于 2010-12-14 08:37:36 | 只看该作者
好贴,楼主的无私奉献精神让人钦佩,PQ的脚本能够做到全自动分区操作真是不错。
回复

使用道具 举报

136#
发表于 2009-3-3 15:17:27 | 只看该作者
原帖由 Climbing 于 2009-3-3 13:35 发表
基本上都属于过时的东西了,现在没有多少人用这个了吧?


可能用的人不是很多,但并非过时。
估计还没人能超越。
回复

使用道具 举报

135#
 楼主| 发表于 2009-3-3 13:35:07 | 只看该作者
基本上都属于过时的东西了,现在没有多少人用这个了吧?
回复

使用道具 举报

134#
发表于 2009-3-2 19:56:56 | 只看该作者
这么好的帖子,沉了这么久?可惜可惜
回复

使用道具 举报

133#
发表于 2009-3-2 19:45:41 | 只看该作者
经典中的经典。
顶一下。
回复

使用道具 举报

132#
发表于 2009-3-2 18:25:07 | 只看该作者
不知现在还有改进否?
回复

使用道具 举报

131#
发表于 2009-2-27 01:37:10 | 只看该作者
感谢分享
有时间研究一下
回复

使用道具 举报

130#
发表于 2009-2-20 11:38:59 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

129#
发表于 2009-2-18 13:55:40 | 只看该作者
楼上挖坟啊?
不过国产diskgen升级了,推出了windows版的
回复

使用道具 举报

128#
发表于 2009-2-18 13:38:51 | 只看该作者
我这样的菜鸟都能将这个帖子看懂个大概意思 ,好帖啊!
回复

使用道具 举报

127#
发表于 2009-2-10 14:44:11 | 只看该作者
学习了。
不错。很强大啊
回复

使用道具 举报

126#
发表于 2008-8-24 14:08:08 | 只看该作者
厉害!
只是这样的技术恐怕好不容易学会了,也很少能碰到非要这样使用的时候。
回复

使用道具 举报

125#
发表于 2008-8-24 09:59:47 | 只看该作者
我需要慢慢地学习-菜鸟嘛,能有简单明了的更好?谢谢
回复

使用道具 举报

124#
发表于 2008-5-30 20:57:13 | 只看该作者
你来迟了,这个早有人做出来啦。基本上网络上流行的个人创建一键恢复软件的分区方法都和这个有因缘。
回复

使用道具 举报

123#
发表于 2008-5-30 15:44:04 | 只看该作者
好,居然有这么好的东东,和娃兄的结合起来,就无敌了
回复

使用道具 举报

122#
发表于 2008-4-25 21:46:53 | 只看该作者
作个记号,收藏备用。
回复

使用道具 举报

121#
发表于 2008-4-24 15:21:21 | 只看该作者
非常有用,有时间了研究一下。
回复

使用道具 举报

120#
发表于 2008-4-24 14:14:35 | 只看该作者
相见恨晚且受益匪浅哪!收藏了。
回复

使用道具 举报

119#
发表于 2008-4-22 18:08:49 | 只看该作者
太牛了。老大!

你真的强
回复

使用道具 举报

118#
发表于 2008-4-22 17:53:09 | 只看该作者
我终于知道一键还原是怎末调整分区的了
回复

使用道具 举报

117#
发表于 2008-4-22 12:48:46 | 只看该作者
一个字——牛,要是能做成图形化,用鼠标操作就好了。
俺们可是菜啊
回复

使用道具 举报

116#
发表于 2008-4-20 19:38:33 | 只看该作者
好贴。支持哈。呵呵……
回复

使用道具 举报

115#
发表于 2008-4-13 13:37:27 | 只看该作者
这杯陈年好酒建议加精置顶。
回复

使用道具 举报

114#
发表于 2008-4-13 13:33:29 | 只看该作者
好帖,从头看到尾了。
老毛桃的“=”     “ = ”真是强!!!!!!!
老毛桃就是老毛桃。
对一键恢复还原的粉丝来说真是一个不可多得的教程。
回复

使用道具 举报

113#
发表于 2008-4-13 11:18:35 | 只看该作者
顶起来,这么好的帖子。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-5-10 02:20

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表