itljl 发表于 2010-3-11 09:37:59

[已解决]请教百分比的获取

本帖最后由 itljl 于 2010-3-11 12:23 编辑

有知道的朋友分享一下,不知道的朋友我们一起找相关函数。
另,可别说打开任务管理器获取控件数据啊。

itljl 发表于 2010-3-11 09:45:01

方法一,但经常获取到的数据为空(非0)

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$strComputer = "localhost"

$Output=""
$Output = $Output & "Computer: " & $strComputer& @CRLF
$Output = $Output & "==========================================" & @CRLF
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapter", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   For $objItem In $colItems
      $Output = $Output & "AdapterType: " & $objItem.AdapterType & @CRLF
      $Output = $Output & "AdapterTypeId: " & $objItem.AdapterTypeId & @CRLF
      $Output = $Output & "AutoSense: " & $objItem.AutoSense & @CRLF
      $Output = $Output & "Availability: " & $objItem.Availability & @CRLF
      $Output = $Output & "Caption: " & $objItem.Caption & @CRLF
      $Output = $Output & "ConfigManagerErrorCode: " & $objItem.ConfigManagerErrorCode & @CRLF
      $Output = $Output & "ConfigManagerUserConfig: " & $objItem.ConfigManagerUserConfig & @CRLF
      $Output = $Output & "CreationClassName: " & $objItem.CreationClassName & @CRLF
      $Output = $Output & "Description: " & $objItem.Description & @CRLF
      $Output = $Output & "DeviceID: " & $objItem.DeviceID & @CRLF
      $Output = $Output & "ErrorCleared: " & $objItem.ErrorCleared & @CRLF
      $Output = $Output & "ErrorDescription: " & $objItem.ErrorDescription & @CRLF
      $Output = $Output & "Index: " & $objItem.Index & @CRLF
      $Output = $Output & "InstallDate: " & WMIDateStringToDate($objItem.InstallDate) & @CRLF
      $Output = $Output & "Installed: " & $objItem.Installed & @CRLF
      $Output = $Output & "LastErrorCode: " & $objItem.LastErrorCode & @CRLF
      $Output = $Output & "MACAddress: " & $objItem.MACAddress & @CRLF
      $Output = $Output & "Manufacturer: " & $objItem.Manufacturer & @CRLF
      $Output = $Output & "MaxNumberControlled: " & $objItem.MaxNumberControlled & @CRLF
      $Output = $Output & "MaxSpeed: " & $objItem.MaxSpeed & @CRLF
      $Output = $Output & "Name: " & $objItem.Name & @CRLF
      $Output = $Output & "NetConnectionID: " & $objItem.NetConnectionID & @CRLF
      $Output = $Output & "NetConnectionStatus: " & $objItem.NetConnectionStatus & @CRLF
      $strNetworkAddresses = $objItem.NetworkAddresses(0)
      $Output = $Output & "NetworkAddresses: " & $strNetworkAddresses & @CRLF
      $Output = $Output & "PermanentAddress: " & $objItem.PermanentAddress & @CRLF
      $Output = $Output & "PNPDeviceID: " & $objItem.PNPDeviceID & @CRLF
      $strPowerManagementCapabilities = $objItem.PowerManagementCapabilities(0)
      $Output = $Output & "PowerManagementCapabilities: " & $strPowerManagementCapabilities & @CRLF
      $Output = $Output & "PowerManagementSupported: " & $objItem.PowerManagementSupported & @CRLF
      $Output = $Output & "ProductName: " & $objItem.ProductName & @CRLF
      $Output = $Output & "ServiceName: " & $objItem.ServiceName & @CRLF
      $Output = $Output & "Speed: " & $objItem.Speed & @CRLF
      $Output = $Output & "Status: " & $objItem.Status & @CRLF
      $Output = $Output & "StatusInfo: " & $objItem.StatusInfo & @CRLF
      $Output = $Output & "SystemCreationClassName: " & $objItem.SystemCreationClassName & @CRLF
      $Output = $Output & "SystemName: " & $objItem.SystemName & @CRLF
      $Output = $Output & "TimeOfLastReset: " & WMIDateStringToDate($objItem.TimeOfLastReset) & @CRLF
      if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
      $Output=""
   Next
Else
   Msgbox(0,"WMI 输出","No WMI Objects Found for class: " & "Win32_NetworkAdapter" )
Endif


Func WMIDateStringToDate($dtmDate)

        Return (StringMid($dtmDate, 5, 2) & "/" & _
        StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
        & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate,13, 2))
EndFunc

pusofalse 发表于 2010-3-11 10:58:10

试下这样可否~?
Const $tagMIB_IFROW = "wchar Name;dword Index;dword Type;dword Mtu;dword Speed;dword PhysicalAddrLen;byte PhysicalAddr;dword AdminStatus;dword OperStatus;dword LastChange;dword InOctets;dword InUcastPkts;dword InNUcastPkts;dword InDiscards;dword InErrors;dword InUnknownProtos;dword OutOctets;dword OutUcastPkts;dword OutNUcastPkts;dword OutDiscards;dword OutErros;dword OutQLen;dword DescrLen;char Descr"

Local $aIfEntry = _EnumIfEntries()
Local $iPrevInOctets = $aIfEntry
Local $iPrevOuOctets = $aIfEntry
Local $iCurrOctets, $iCurrOuOctets, $iCurrInOctets, $iIfIndex

For $i = 1 To $aIfEntry
        If ($aIfEntry[$i] = 6) Then
                $iIfIndex = $aIfEntry[$i]
                ExitLoop
        EndIf
Next
If ($iIfIndex = 0) Then Exit

HotKeySet("{esc}", "_Quit")

While 1
        $aIfEntry = _EnumIfEntries()
        $iCurrInOctets = $aIfEntry[$iIfIndex] - $iPrevInOctets
        $iCurrOuOctets = $aIfEntry[$iIfIndex] - $iPrevOuOctets
        $iPrevInOctets = $aIfEntry[$iIfIndex]
        $iPrevOuOctets = $aIfEntry[$iIfIndex]
        $iCurrOctets = $iCurrInOctets + $iCurrOuOctets

        ToolTip(Round($iCurrOctets / $aIfEntry[$iIfIndex] * 1000, 2))
        $aIfEntry = 0
        Sleep(900)
WEnd

Func _Quit()
        exit
EndFunc        ;==>_Quit

Func _EnumIfEntries()
        Local $iResult, $tBuffer, $pBuffer, $tIfEntry, $tCount, $aResult

        $iResult = DllCall("iphlpapi.dll", "dword", "GetIfTable", "ptr", 0, "ulong*", 0, "int", 1)
        $tBuffer = DllStructCreate("ubyte Binary[" & $iResult & "]")
        $pBuffer = DllStructGetPtr($tBuffer, "Binary")

        $iResult = DllCall("iphlpapi.dll", "dword", "GetIfTable", "ptr", $pBuffer, _
                        "ulong*", $iResult, "int", 1)
        $tCount = DllStructCreate("ulong NumberofEntries", $pBuffer)
        $aResult = DllStructGetData($tCount, "NumberofEntries")
        Redim $aResult[$aResult + 1]

        $pBuffer += 4
        For $i = 1 To $aResult
                $tIfEntry = DllStructCreate($tagMIB_IFROW, $pBuffer)
                $pBuffer += DllStructGetSize($tIfEntry)

                $aResult[$i] = DllStructGetData($tIfEntry, "Name")
                $aResult[$i] = DllStructGetData($tIfEntry, "Descr")
                $aResult[$i] = DllStructGetData($tIfEntry, "Index")
                $aResult[$i] = DllStructGetData($tIfEntry, "Type")
                $aResult[$i] = DllStructGetData($tIfEntry, "Speed")
                $aResult[$i] = DllStructGetData($tIfEntry, "PhysicalAddr")
                $aResult[$i] = DllStructGetData($tIfEntry, "AdminStatus")
                $aResult[$i] = DllStructGetData($tIfEntry, "OperStatus")
                $aResult[$i] = DllStructGetData($tIfEntry, "InOctets")
                $aResult[$i] = DllStructGetData($tIfEntry, "OutOctets")
                $tIfEntry = 0
        Next
        $tBuffer = 0
        Return SetError($iResult, 0, $aResult)
EndFunc        ;==>_EnumIfEntries

itljl 发表于 2010-3-11 11:10:47

回复 3# pusofalse

谢谢,很帅,xp sp2 测试正常。

pusofalse 发表于 2010-3-11 11:14:23

如果做成任务管理器那般的曲线图就更好了,苦于对绘图方面的代码一窍不通~ - -|||

itljl 发表于 2010-3-11 11:18:44

回复 5# pusofalse

这个我来绘,等等。
但有个问题Sleep(900) ,必须是这个值 。如果改成 sleep(2000)就不准了。之所以有这个问题主要是,程序可能还有其它代码会执行,不是只执行这一段代码。

pusofalse 发表于 2010-3-11 11:25:23

不是不准,而是与任务管理器中显示的不同步,其实线性关系是一样的。
上面的代码,我为了与任务管理器的同步,调试了好一阵才确定为900的。

itljl 发表于 2010-3-11 11:32:43

回复 7# pusofalse

Const $tagMIB_IFROW = "wchar Name;dword Index;dword Type;dword Mtu;dword Speed;dword PhysicalAddrLen;byte PhysicalAddr;dword AdminStatus;dword OperStatus;dword LastChange;dword InOctets;dword InUcastPkts;dword InNUcastPkts;dword InDiscards;dword InErrors;dword InUnknownProtos;dword OutOctets;dword OutUcastPkts;dword OutNUcastPkts;dword OutDiscards;dword OutErros;dword OutQLen;dword DescrLen;char Descr"

Local $aIfEntry = _EnumIfEntries()
Local $iPrevInOctets = $aIfEntry
Local $iPrevOuOctets = $aIfEntry
Local $iCurrOctets, $iCurrOuOctets, $iCurrInOctets, $iIfIndex

For $i = 1 To $aIfEntry
        If ($aIfEntry[$i] = 6) Then
                $iIfIndex = $aIfEntry[$i]
                ExitLoop
        EndIf
Next
If ($iIfIndex = 0) Then Exit

HotKeySet("{esc}", "_Quit")

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ProgressConstants.au3>

Global $IDLETIME, $KERNELTIME, $USERTIME
Global $StartIdle, $StartKernel, $StartUser
Global $EndIdle, $EndKernel, $EndUser
Global $Timer
$hGUI = GUICreate("CPUmon", 400, 300, -1, -1, 0x80800000);, $WS_EX_TOPMOST)
GUISetBkColor(0x000000)

GUICtrlCreateGraphic(0, 0, 400, 300)
GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x008040)
For $y = 25 To 375 Step 25
        GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 0, $y)
        GUICtrlSetGraphic(-1, $GUI_GR_LINE, 400, $y)
Next
For $x = 25 To 575 Step 25
        GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $x, 0)
        GUICtrlSetGraphic(-1, $GUI_GR_LINE, $x, 300)
Next

$gr = GUICtrlCreateGraphic(0, 50, 400, 300)
$lb = GUICtrlCreateLabel("测试数据", 300, 200, 25, 25)
GUICtrlSetColor(-1, 0x00FF00)
GUISetState()
GUICtrlSetGraphic($gr, $GUI_GR_COLOR, 0x00FF00)

$x = 0
$y = 0
$dx = 400
$dy = 300
GUICtrlSetGraphic($gr, $GUI_GR_MOVE, $dx, $dy)

;绘图示例
;~ ;$Y | ,$x _
While 1
        $dx += 10 ;X轴两个点之间的间隔
        $dy = Random(50, 250, 1) ;产生随机数,在1-100之间都行
        GUICtrlSetGraphic($gr, $GUI_GR_LINE, $dx, $dy) ;$dx $dy
        GUICtrlSetGraphic($gr, $GUI_GR_REFRESH)
        $x -= 2
        GUICtrlSetPos($gr, $x, $y)
        GUICtrlSetPos($lb, $x + 300, $y)
        Sleep(100)
WEnd



While 1
        $aIfEntry = _EnumIfEntries()
        $iCurrInOctets = $aIfEntry[$iIfIndex] - $iPrevInOctets
        $iCurrOuOctets = $aIfEntry[$iIfIndex] - $iPrevOuOctets
        $iPrevInOctets = $aIfEntry[$iIfIndex]
        $iPrevOuOctets = $aIfEntry[$iIfIndex]
        $iCurrOctets = $iCurrInOctets + $iCurrOuOctets


        $dx += 10 ;X轴两个点之间的间隔
        $dy = Round($iCurrOctets / $aIfEntry[$iIfIndex] * 1000, 0) ;计算

        ToolTip("检测网络使用率: " & $dy & " %", 10, 10)
        ;绘图开始

        GUICtrlSetGraphic($gr, $GUI_GR_LINE, $dx, $dy) ;$dx $dy

        GUICtrlSetGraphic($gr, $GUI_GR_REFRESH)
        $x -= 2
        GUICtrlSetPos($gr, $x, $y)
        GUICtrlSetPos($lb, $x + 300, $y)
        ;绘图结束
        $aIfEntry = 0
        Sleep(500)
WEnd

Func _Quit()
        Exit
EndFunc   ;==>_Quit

Func _EnumIfEntries()
        Local $iResult, $tBuffer, $pBuffer, $tIfEntry, $tCount, $aResult

        $iResult = DllCall("iphlpapi.dll", "dword", "GetIfTable", "ptr", 0, "ulong*", 0, "int", 1)
        $tBuffer = DllStructCreate("ubyte Binary[" & $iResult & "]")
        $pBuffer = DllStructGetPtr($tBuffer, "Binary")

        $iResult = DllCall("iphlpapi.dll", "dword", "GetIfTable", "ptr", $pBuffer, _
                        "ulong*", $iResult, "int", 1)
        $tCount = DllStructCreate("ulong NumberofEntries", $pBuffer)
        $aResult = DllStructGetData($tCount, "NumberofEntries")
        ReDim $aResult[$aResult + 1]

        $pBuffer += 4
        For $i = 1 To $aResult
                $tIfEntry = DllStructCreate($tagMIB_IFROW, $pBuffer)
                $pBuffer += DllStructGetSize($tIfEntry)

                $aResult[$i] = DllStructGetData($tIfEntry, "Name")
                $aResult[$i] = DllStructGetData($tIfEntry, "Descr")
                $aResult[$i] = DllStructGetData($tIfEntry, "Index")
                $aResult[$i] = DllStructGetData($tIfEntry, "Type")
                $aResult[$i] = DllStructGetData($tIfEntry, "Speed")
                $aResult[$i] = DllStructGetData($tIfEntry, "PhysicalAddr")
                $aResult[$i] = DllStructGetData($tIfEntry, "AdminStatus")
                $aResult[$i] = DllStructGetData($tIfEntry, "OperStatus")
                $aResult[$i] = DllStructGetData($tIfEntry, "InOctets")
                $aResult[$i] = DllStructGetData($tIfEntry, "OutOctets")
                $tIfEntry = 0
        Next
        $tBuffer = 0
        Return SetError($iResult, 0, $aResult)
EndFunc   ;==>_EnumIfEntries


绘图。调整$dy 在 100以内,就能按比例显示了。超过100就超过了绘图控件的顶端。
第一个循环是演示,第二个循环是显示网络连接使用率

itljl 发表于 2010-3-11 11:42:00

回复 7# pusofalse



我测试了一下,如果sleep时间多一秒获得的使用率就会多一倍(图是我改成3000的时候的截图)。
所以,如果将这个放到其它程序物循环中,其它程序的的其它函数如果占用了时间,这个获取的使用率就不准了。
所以,我想应该是获取一个系统时间,最后程序计算使用率的时候,用使用率来/时间,这样才是每秒的使用率。

itljl 发表于 2010-3-11 11:53:09

回复 9# itljl


    用 $dif = TimerDiff($begin) 解决了这个问题。。

lxz 发表于 2010-3-11 12:01:57

很好,很强大......

itljl 发表于 2010-3-11 12:05:41

刚想编辑贴子为已解决,发现没有这个选项了。。

pusofalse 发表于 2010-3-11 12:17:54

回复 12# itljl


    是的,现在的帖子分类已经去掉“已解决”了,给帖子标题手动加注“已解决”字样即可。
页: [1]
查看完整版本: [已解决]请教百分比的获取