Harddisk Kapazität ermitteln

  • Hallo zusammen

    gibt es eine Möglichkeit die genaue Grösse einer Harddisk zu ermittlen? Nach Möglichkeit sollte die Grösse in GB oder MB ermittelt werden.

    MfG
    johny1099

    Einmal editiert, zuletzt von johny1099 (10. August 2010 um 22:06)

  • vielen Dank für die schnelle Beantwortung meiner Frage.

    Die Funktion DriveSpaceTotal() funktioniert einwandfrei bei einem installiertem Betriebssystem mit vorhandener Partition (Drive C:\)

    Ich hatte leider nicht erwähnt dass ich folgende Problemstellung habe.

    Ich habe einen PC mit dem ich unter Windows PE 3.0 boote. Die Harddisk ist zu diesem Zeitpunkt noch nicht partitioniert und hat daher noch keine Partitionsinformationen. Daher sind auch keine Laufwerke vorhanden.
    Gibt es eine Möglichkeit trotzdem die Harddiskgrösse zu ermitteln auch wenn keine Partitionen erstellt sind?

    Mfg
    johny1099

  • Hm du könntest mit disk part "list disk" ausführen, dort bekommst du die Volumegröße angezeigt & mit "list partition" die Partitionen

    21 is only half the truth.

  • vielen Dank für die schnelle Beantwortung meiner Frage.

    gibt es keine AutoIt Funktion anstatt diskpart.exe bzw. list disk Commands?

    Das Problem ist ich möchte diese Informationen automatisiert durchführen lassen und die Grösse der Harddisk z.b in einer Variable speichern und danach weiter verarbeiten.

    MfG
    johny1099

    • Offizieller Beitrag

    Hilft Dir das hier weiter:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    $aDrives = _CI_GetHarddrives()
    _ArrayDisplay($aDrives)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _CI_GetHarddrives($strComputer = '.')
    Local $aReturn[1][7] = [[ _
    'Bezeichnung:', 'Größe:', 'Anschluss:', 'Bytes/Sektor:', 'Anzahl der Sektoren:', _
    'PNPDeviceID:', 'Status:']]
    Local $x = 0, $objWMIService, $colItems
    $objWMIService = ObjGet('winmgmts:\\' & $strComputer & '\root\cimv2')
    If Not IsObj($objWMIService) Then Return SetError(1, 0, 0)
    $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_DiskDrive', 'WQL', 0x30)
    If IsObj($colItems) Then
    For $objItem In $colItems
    $x += 1
    ReDim $aReturn[$x + 1][7]
    $aReturn[$x][0] = $objItem.Model
    $aReturn[$x][1] = $objItem.Size
    $aReturn[$x][2] = $objItem.InterfaceType
    $aReturn[$x][3] = $objItem.BytesPerSector
    $aReturn[$x][4] = $objItem.TotalSectors
    $aReturn[$x][5] = $objItem.PNPDeviceID
    $aReturn[$x][6] = $objItem.Status
    Next
    EndIf
    Return $aReturn
    EndFunc ;==>_CI_GetHarddrives

    [/autoit]
  • Mit PE 3.0 hab ich noch nicht gearbeitet. Frühere Versionen hatten die Einschränkung, das WMI nicht funktionierte.
    Falls Oscars vorschlag daher nicht funktioniert, versuche doch das programm diskpart zu automatisieren.
    Helfen könnte dabei der Run-Befehl mit den zusätzlichen Parametern $STDOUT_CHILD und $STDERR_CHILD.

    Falls du damit auch nicht weiterkommst kannst du die Ausgabe von diskpart in eine Datei umleiten lassen.
    Dazu brauchst du allerdings ein Skript.

    Skript:
    "list disk" -> speichern als skript.txt

    Befehl:
    Run(@ComSpec & " /c " & 'diskpart /s skript.txt > ausgabe.txt', "", @SW_HIDE)

    Nicht unbedingt schön, aber geht. Musst allerdings noch den Pfad zum RAM-Laufwerk angeben

  • Falls WMI unter PE nicht funktioniert und es wirklich nur um die Größe der Datenträger geht dann noch ein Vorschlag:

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $aArr = _GetHDDSizes()
    _ArrayDisplay($aArr)

    [/autoit] [autoit][/autoit] [autoit]

    ;Gibt die Größen aller Massenspeicher im System zurück(in GiB), $aReturn[0] = Größe des Arrays
    Func _GetHDDSizes()
    ;by AspirinJunkie
    Local $tStrct = DllStructCreate("int64;dword;dword;dword;dword;int64;dword")
    Local $hFile, $aDllRet, $aRet[1], $iDrive = 0
    Local $hKernelDll = DllOpen('kernel32.dll')

    [/autoit] [autoit][/autoit] [autoit]

    Do
    $hFile = _WinAPI_CreateFile('\\.\PhysicalDrive' & $iDrive, 2)
    If $hFile = 0 Then ExitLoop

    [/autoit] [autoit][/autoit] [autoit]

    $aDllRet = DllCall($hKernelDll, 'int', 'DeviceIoControl', 'ptr', $hFile, 'dword', 0x000700A0, 'ptr', 0, 'dword', 0, 'ptr', DllStructGetPtr($tStrct), 'dword', DllStructGetSize($tStrct), 'ptr*', 0, 'ptr', 0)
    If @error or (Not IsArray($aDllRet)) Or $aDllRet[0] = 0 Then Return SetError(1, @error, 0)

    [/autoit] [autoit][/autoit] [autoit]

    $iDrive += 1
    ReDim $aRet[$iDrive + 1]
    $aRet[0] += 1
    $aRet[$iDrive] = DllStructGetData($tStrct, 6) / 2 ^ 30

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_CloseHandle($hFile)
    Until 0
    Return $aRet
    EndFunc

    [/autoit]
  • Hallo Oscar, auch Dir vielen Dank für die schnelle Antwort.

    Ich habe das Script getestet und soweit ich das beurteile funktioniert es korrekt.

    Meine Harddisk ist 160 GB gross.
    Das Script liefert als Wert in der Variable $objItem.Size ==> 160038789120 zurück

    Kann ich diesen Wert immer umrechnen in GB, oder spielen auch die Spalten Bytes/Sektor bzw Anzahl Sektoren eine Rolle bei der Umrechnung?

    Welcher Wert wird momentan angezeigt (160038789120) Bit, Byte, Kilobyte??

    • Offizieller Beitrag

    Ja, das sind Bytes.

    Ich hätte da auch noch eine Funktion zum umrechnen (in KB, MB, GB oder automatisch):

    Spoiler anzeigen
    [autoit]


    ;===============================================================================
    ; Function Name: _ByteAutoSize($iSize[, $iRound][, $iFormat][, $bThousands])
    ; Description:: Gibt einen Bytewert in einer bestimmten Einheit zurück
    ; Parameter(s): $iSize = Größe in Byte übergeben
    ; $iRound = Anzahl der Nachkommastellen (0...8)
    ; $iFormat = bestimmt den Rückgabewert
    ; 0 = Automatisch (je nach übergebenen Wert)
    ; 1 = in Byte
    ; 2 = in KByte
    ; 3 = in MByte
    ; 4 = in GByte
    ; $bThousands = Rückgabe mit Tausendertrennzeichen (True/False)
    ; Requirement(s): #include <String.au3>
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _ByteAutoSize($iSize, $iRound = 2, $iFormat = 0, $bThousands = True)
    Local $aSize[4] = [' Byte', ' KByte', ' MByte', ' GByte'], $sReturn
    If $iFormat < 0 Or $iFormat > 4 Then $iFormat = 0
    If $iRound < 0 Or $iRound > 8 Then $iRound = 2
    If Not IsBool($bThousands) Then $bThousands = False
    $iSize = Abs($iSize)
    If $iFormat = 0 Then
    For $i = 30 To 0 Step -10
    If $iSize > (2 ^ $i) Then
    $iFormat = $i / 10 + 1
    ExitLoop
    EndIf
    Next
    EndIf
    If $iFormat = 0 Then $iFormat = 1
    $sReturn = StringFormat('%.' & $iRound & 'f', Round($iSize / (2 ^ (($iFormat - 1) * 10)), $iRound))
    If $bThousands Then $sReturn = _StringAddThousandsSep($sReturn, '.', ',')
    Return $sReturn & $aSize[$iFormat - 1]
    EndFunc ;==>_ByteAutoSize

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _StringAddThousandsSep
    ; Description ...: Returns the original numbered string with the Thousands delimiter inserted.
    ; Syntax.........: _StringAddThousandsSep($sString[, $sThousands = -1[, $sDecimal = -1]])
    ; Parameters ....: $sString - The string to be converted.
    ; $sThousands - Optional: The Thousands delimiter
    ; $sDecimal - Optional: The decimal delimiter
    ; Return values .: Success - The string with Thousands delimiter added.
    ; Author ........: SmOke_N (orignal _StringAddComma
    ; Modified.......: Valik (complete re-write, new function name)
    ; ===============================================================================================================================
    Func _StringAddThousandsSep($sString, $sThousands = -1, $sDecimal = -1)
    Local $sResult = "" ; Force string
    Local $rKey = "HKCU\Control Panel\International"
    If $sDecimal = -1 Then $sDecimal = RegRead($rKey, "sDecimal")
    If $sThousands = -1 Then $sThousands = RegRead($rKey, "sThousand")
    Local $aNumber = StringRegExp($sString, "(\D?\d+)\D?(\d*)", 1) ; This one works for negatives.
    If UBound($aNumber) = 2 Then
    Local $sLeft = $aNumber[0]
    While StringLen($sLeft)
    $sResult = $sThousands & StringRight($sLeft, 3) & $sResult
    $sLeft = StringTrimRight($sLeft, 3)
    WEnd
    $sResult = StringTrimLeft($sResult, StringLen($sThousands)) ; Strip leading thousands separator
    If $aNumber[1] <> "" Then $sResult &= $sDecimal & $aNumber[1]
    EndIf
    Return $sResult
    EndFunc ;==>_StringAddThousandsSep

    [/autoit]
  • Danke allen Beteiligten die zur Lösung meines Problems beigetragen haben.

    Jetzt muss ich nur noch die Funktionen unter die Lupe nehmen damit ich dass auch alles richtig verstehe.

    MfG
    johny1099