1、用 vb获得大容量硬盘信息_visualbasic 教程这是为什么呢?熟悉 Win32API 编程的人都知道,在用 VB 编程时,我们可以用相应的 API 函数来获得有关系 统的硬盘的信息,会不会是错在 API 的调用函数呢?想到 这里我用自 编的程序来查看PCAlert 的有关文件,发现其调用了 GetDiskFreeSpace 函数,问题就出在这个函数上。下面是该函数的参数说明:ByvallpRootPathNameAsString(为欲查看的分区的根路径如 C:),lpSectorsPerClusterAsLong(为一簇的扇区数) ,lpBytesPerSectorAsLong(为每一
2、扇区的字节 数),lpNumberOfFreeClustersAsLong(当前分区中未使用的簇数),lpTotalNumberOfClustersAsLong(总的簇数) AsLong。当我们调用此函数时,是以lpBytesPerSectorlpSectorsPerClusterTotalNumberOfClusters 来计算分区总的大小的,在 VB 中我用来查看自己的 C 盘时返回值分别为512、64、65526,因而 计 算出的 C 盘的大小只有 2.05G。 以下是关于 MSDN 中的有关详细说明:对于大于的 2G 分区,GetDiskFreeSpace 函数可能(什么可能,是一定!
3、)返回错误的值,此时函数会屏蔽存在 lpNumberOfFreeClusters 及lpTotalNumberOfClusters 中的值,因此建议 不要用该函数来获得大于2G 分区的信息。对于大于 2G 的分区应当使用 GetDiskFreeSpaceEx函数(从 Win95OEMOSR2 开始),此函数可以返回分区的有关正确信息。找到了问题所在便可以对症下药了,即用 GetDiskFreeSpaceEx 函数代替 GetDiskFreeSpace 函数即可。以下是 GetDiskFreeSpaceEx 函数中所要传递增的参数lpRootPathNameString ,不包括卷名的磁盘根路径
4、名lpFreeBytesAvailableToCallerLARGE_INTEGER,指定一个 变量,用于容纳调用者可用的字节数量lpTotalNumberOfBytesLARGE_INTEGER ,指定一个变量,用于容纳磁盘上的总字节数lpTotalNumberOfFreeBytesLARGE_INTEGER,指定一个变量,用于容纳磁盘上可用的字节数PrivateTypeLARGE_INTEGERlowpartAsLonghighpartAsLongEndType我们可以看到 LARGE_INTEGER 是一个由两个 long 型组成的一个类型,两个 long 组成表示的都是无符号的数,在转
5、换时应当定义一个 single 型的变量,使其等于 highpart*(232-1) lowpart,注意此处的两个 long 型相当于 C/C 中的无符号型整数 类型,因 为在 VB 中不存在此种类型,故而在换算时要处理好转换关系。我本人的做法是首先判断 long 型变量的正负,如是正直接相乘,如是负则用 232-1 减去该值再相乘(具体算法详见下面的代码)。OptionExplicitPrivateTypeLARGE_INTEGERlowpartAsLonghighpartAsLongEndTypePrivateDeclareFunctionGetDiskFreeSpaceLib“kern
6、el32“Alias“GetDiskFreeSpaceA“(ByVallpRootPathNameAsString,lpSectorsPerClusterAsLong,lpBytesPerSectorAsLong,lpNumberOfFreeClustersAsLong,lpTotalNumberOfClustersAsLong)AsLongPrivateDeclareFunctionGetDiskFreeSpaceExLib“kernel32“Alias“GetDiskFreeSpaceExA“_(ByVallpRootPathNameAsString,lpFreeBytesAvailabl
7、eToCallerAsLARGE_INTEGER,_lpTotalNumberOfBytesAsLARGE_INTEGER,lpTotalNumberOfFreeBytes_AsLARGE_INTEGER)AsLongPrivateSubCommand1_Click()DimlngSectors&DimlngTotalCluster&DimlngFreeCluster&DimlngPerCluster&DimlngperBytes&DimlngSize#GetDiskFreeSpace“c:“,lngPerCluster,lngperBytes,lngFreeCluster,lngTotalC
8、lusterMsgBoxCStr(lngTotalCluster*lngperBytes*lngPerCluster)Debug.PrintlngTotalCluster,lngperBytes,lngPerClusterEndSubPrivateTypeLARGE_INTEGERlowpartAsLonghighpartAsLongEndTypePrivateDeclareFunctionGetDiskFreeSpaceLib“kernel32“Alias“GetDiskFreeSpaceA“(ByVallpRootPathNameAsString,lpSectorsPerClusterAs
9、Long,lpBytesPerSectorAsLong,lpNumberOfFreeClustersAsLong,lpTotalNumberOfClustersAsLong)AsLongPrivateDeclareFunctionGetDiskFreeSpaceExLib“kernel32“Alias“GetDiskFreeSpaceExA“_(ByVallpRootPathNameAsString,lpFreeBytesAvailableToCallerAsLARGE_INTEGER,_lpTotalNumberOfBytesAsLARGE_INTEGER,lpTotalNumberOfFr
10、eeBytes_AsLARGE_INTEGER)AsLongPrivateSubCommand1_Click()注释:用 GetDiskFreeSpace 得到错误的容量DimlngSectors&DimlngTotalCluster&DimlngFreeCluster&DimlngPerCluster&DimlngperBytes&DimlngSize#GetDiskFreeSpace“c:“,lngPerCluster,lngperBytes,lngFreeCluster,lngTotalClusterMsgBoxCStr(lngTotalCluster*lngperBytes*lngPe
11、rCluster)EndSubPrivateSubcmdStart_Click()注释:用 GetDiskFreeSpaceEx 得到正确的容量DimlngFreeCallerAsLARGE_INTEGERDimlngTotalAsLARGE_INTEGERDimlngTotalFreeAsLARGE_INTEGERDimsngSize#GetDiskFreeSpaceEx“c:“,lngFreeCaller,lngTotal,lngTotalFree注释:以下用来显示出分区总容量(以 G 为单位)MsgBoxGetSize(lngTotal)/230EndSubPrivateFunction
12、GetSize(lngSizeAsLARGE_INTEGER)AsSingle注释:用来从 LARGE_INTEGER 型变量中换算出实际的大小WithlngSizeIf.highpart0ThenGetSize=(232-1-.highpart)*(232-1)ElseGetSize=.highpart*(232-1)EndIfIf.lowpart0ThenGetSize=GetSize (232-1-.lowpart)ElseGetSize=GetSize .lowpartEndIfEndWithEndFunctionPrivateFunctionGetSize(lngSizeAsLARG
13、E_INTEGER)AsSingle注释:用来从 LARGE_INTEGER 型变量中 换算出实际的大小WithlngSizeIf.highpart0ThenGetSize=(232-1-.highpart)*(232-1)ElseGetSize=.highpart*(232-1)EndIfIf.lowpart0ThenGetSize=GetSize (232-1-.lowpart)ElseGetSize=GetSize .lowpartEndIfEndWithEndFunction从 LARGE_INTEGER 的定义来看, 应用此函数理论上可得到264/230=234G 的分区的大小,不知这辈子能否用上这么大的硬盘