[Asm] 纯文本查看 复制代码
#RequireAdmin
#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=
#AutoIt3Wrapper_Outfile=ComputerInfoCollector.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseUpx=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <File.au3>
#include <String.au3>
; 定义资源文件路径和提取路径
Global $sBinDir = @TempDir & "\bin"
Global $sMonitorInfoDir = @TempDir & "\monitorinfoview"
; 创建临时目录
DirCreate($sBinDir)
DirCreate($sMonitorInfoDir)
; 嵌入bin目录下的文件
FileInstall("bin\drivedb.h", $sBinDir & "\drivedb.h", 1)
FileInstall("bin\runcmdu.exe", $sBinDir & "\runcmdu.exe", 1)
FileInstall("bin\smartctl-nc.exe", $sBinDir & "\smartctl-nc.exe", 1)
FileInstall("bin\smartctl.exe", $sBinDir & "\smartctl.exe", 1)
FileInstall("bin\smartd.conf", $sBinDir & "\smartd.conf", 1)
FileInstall("bin\smartd.exe", $sBinDir & "\smartd.exe", 1)
FileInstall("bin\smartd_mailer.conf.sample.ps1", $sBinDir & "\smartd_mailer.conf.sample.ps1", 1)
FileInstall("bin\smartd_mailer.ps1", $sBinDir & "\smartd_mailer.ps1", 1)
FileInstall("bin\smartd_warning.cmd", $sBinDir & "\smartd_warning.cmd", 1)
FileInstall("bin\update-smart-drivedb.ps1", $sBinDir & "\update-smart-drivedb.ps1", 1)
FileInstall("bin\wtssendmsg.exe", $sBinDir & "\wtssendmsg.exe", 1)
; 嵌入monitorinfoview目录下的文件
FileInstall("monitorinfoview\MonitorInfoView.cfg", $sMonitorInfoDir & "\MonitorInfoView.cfg", 1)
FileInstall("monitorinfoview\MonitorInfoView.chm", $sMonitorInfoDir & "\MonitorInfoView.chm", 1)
FileInstall("monitorinfoview\MonitorInfoView.exe", $sMonitorInfoDir & "\MonitorInfoView.exe", 1)
FileInstall("monitorinfoview\MonitorInfoView_lng.ini", $sMonitorInfoDir & "\MonitorInfoView_lng.ini", 1)
FileInstall("monitorinfoview\readme.txt", $sMonitorInfoDir & "\readme.txt", 1)
FileInstall("monitorinfoview\temp_monitors.csv", $sMonitorInfoDir & "\temp_monitors.csv", 1)
; 启用OnEvent模式
Opt("GUIOnEventMode", 1)
; 全局变量
Global $sCurrentDir = @ScriptDir
Global $iMonitorCount = 1
Global $aMonitorsInfo[0][3] ; 存储显示器详细信息:[品牌型号, 序列号, 大小]
Global $sMonitorDir = $sMonitorInfoDir ; 使用临时目录中的monitorinfoview
; 检查管理员权限
If Not IsAdmin() Then
MsgBox(48, "权限错误", "此程序需要以管理员身份运行!" & @CRLF & "请右键选择""以管理员身份运行""")
Exit
EndIf
; 创建主窗口
Local $hMainGUI = GUICreate("电脑信息收集工具", 920, 680, -1, -1)
GUISetBkColor(0xF0F0F0, $hMainGUI)
GUISetFont(9, 400, 0, "微软雅黑")
; 创建信息显示区域
Local $hInfoGroup = GUICtrlCreateGroup("系统信息", 15, 15, 890, 280)
GUICtrlSetFont(-1, 11, 600, 0, "微软雅黑")
GUICtrlSetColor(-1, 0x2C3E50)
; 计算机名
Local $hLabel1 = GUICtrlCreateLabel("计算机名:", 25, 42, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hComputerName = GUICtrlCreateInput("", 135, 40, 220, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; 用户名
Local $hLabel2 = GUICtrlCreateLabel("用户名:", 375, 42, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hUserName = GUICtrlCreateInput("", 485, 40, 150, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; 系统版本
Local $hLabel3 = GUICtrlCreateLabel("系统版本:", 25, 75, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hOSVersion = GUICtrlCreateInput("", 135, 73, 220, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; CPU型号
Local $hLabel4 = GUICtrlCreateLabel("CPU型号:", 375, 75, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hCPUModel = GUICtrlCreateInput("", 485, 73, 350, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; 内存总大小
Local $hLabel5 = GUICtrlCreateLabel("内存总大小:", 25, 108, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hMemorySize = GUICtrlCreateInput("", 135, 106, 200, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; 操作系统安装日期
Local $hLabel5_1 = GUICtrlCreateLabel("操作系统安装日期:", 375, 108, 120, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hOSInstallDate = GUICtrlCreateInput("", 505, 106, 200, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; 硬盘信息
Local $hLabel6 = GUICtrlCreateLabel("硬盘信息:", 25, 140, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hDiskInfo = GUICtrlCreateEdit("", 135, 138, 700, 55, BitOR($ES_READONLY, $ES_WANTRETURN, $WS_VSCROLL))
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetFont(-1, 9, 400, 0, "Consolas")
; MAC地址
Local $hLabel7 = GUICtrlCreateLabel("MAC地址:", 25, 200, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hMACAddress = GUICtrlCreateInput("", 135, 198, 220, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; IP地址
Local $hLabel8 = GUICtrlCreateLabel("IP地址:", 375, 200, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hIPAddress = GUICtrlCreateInput("", 485, 198, 220, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; 显示器信息(自动获取)
Local $hLabel9 = GUICtrlCreateLabel("显示器信息(自动获取):", 25, 232, 150, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hMonitorAutoInfo = GUICtrlCreateEdit("", 185, 230, 700, 55, BitOR($ES_READONLY, $ES_WANTRETURN, $WS_VSCROLL))
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetFont(-1, 9, 400, 0, "Consolas")
GUICtrlCreateGroup("", -99, -99, 1, 1) ; 关闭组
; 用户输入区域
Local $hInputGroup = GUICtrlCreateGroup("用户输入信息", 15, 305, 890, 320)
GUICtrlSetFont(-1, 11, 600, 0, "微软雅黑")
GUICtrlSetColor(-1, 0x2C3E50)
; 电脑主机编号
Local $hLabel10 = GUICtrlCreateLabel("电脑主机编号:", 25, 332, 110, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hHostNumber = GUICtrlCreateInput("ZDBG02-", 145, 330, 240, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetOnEvent($hHostNumber, "OnHostNumberChange")
; 显示器数量选择(单选按钮)
Local $hLabel11 = GUICtrlCreateLabel("显示器数量:", 405, 332, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hMonitorCount1 = GUICtrlCreateRadio("1个", 515, 330, 60, 24)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
GUICtrlSetState(-1, $GUI_CHECKED)
GUICtrlSetOnEvent(-1, "OnMonitorCountChange")
Local $hMonitorCount2 = GUICtrlCreateRadio("2个", 585, 330, 60, 24)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
GUICtrlSetOnEvent(-1, "OnMonitorCountChange")
; 显示器编号输入
Local $hMonitorGroup = GUICtrlCreateGroup("显示器编号", 25, 365, 860, 70)
GUICtrlSetFont(-1, 9, 600, 0, "微软雅黑")
Local $hLabel12 = GUICtrlCreateLabel("显示器1编号:", 35, 390, 110, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hMonitor1Number = GUICtrlCreateInput("ZDBG01-", 155, 388, 240, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetOnEvent($hMonitor1Number, "OnMonitor1NumberChange")
Local $hMonitor2NumberLabel = GUICtrlCreateLabel("显示器2编号:", 415, 390, 110, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
GUICtrlSetState(-1, $GUI_HIDE)
Local $hMonitor2Number = GUICtrlCreateInput("ZDBG01-", 535, 388, 240, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_HIDE)
GUICtrlSetOnEvent($hMonitor2Number, "OnMonitor2NumberChange")
GUICtrlCreateGroup("", -99, -99, 1, 1)
; 使用部门
Local $hLabel13 = GUICtrlCreateLabel("使用部门:", 25, 450, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hDepartment = GUICtrlCreateCombo("", 135, 448, 150, 28, $CBS_DROPDOWNLIST)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetData(-1, "质量部|财务部|采购部|保密办|技术部|总经办|总体部|软件部|综合部|商务部|生产部", "")
; 责任人
Local $hLabel14 = GUICtrlCreateLabel("责任人:", 320, 450, 80, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hResponsible = GUICtrlCreateInput("", 400, 448, 150, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
; 用途
Local $hLabel15 = GUICtrlCreateLabel("用途:", 570, 450, 50, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hPurpose = GUICtrlCreateCombo("", 620, 448, 140, 28, $CBS_DROPDOWNLIST)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetData(-1, "办公|测试|服务器|中间转换|其他", "")
; 服务端配置
Local $hServerGroup = GUICtrlCreateGroup("服务端配置", 25, 500, 860, 100)
GUICtrlSetFont(-1, 9, 600, 0, "微软雅黑")
; 服务端IP
Local $hLabel16 = GUICtrlCreateLabel("服务端IP:", 45, 530, 80, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hServerIP = GUICtrlCreateInput("127.0.0.1", 135, 528, 150, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
; 服务端端口
Local $hLabel17 = GUICtrlCreateLabel("服务端端口:", 320, 530, 100, 22)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
Local $hServerPort = GUICtrlCreateInput("8000", 430, 528, 80, 26)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlCreateGroup("", -99, -99, 1, 1) ; 关闭组
GUICtrlCreateGroup("", -99, -99, 1, 1) ; 关闭组
; 按钮
Local $hCollectBtn = GUICtrlCreateButton("收集系统信息", 15, 640, 130, 35)
GUICtrlSetFont(-1, 10, 600, 0, "微软雅黑")
GUICtrlSetBkColor(-1, 0x3498DB)
GUICtrlSetColor(-1, 0xFFFFFF)
Local $hSaveBtn = GUICtrlCreateButton("保存报告", 160, 640, 130, 35)
GUICtrlSetFont(-1, 10, 600, 0, "微软雅黑")
GUICtrlSetBkColor(-1, 0x27AE60)
GUICtrlSetColor(-1, 0xFFFFFF)
Local $hSendBtn = GUICtrlCreateButton("发送到服务端", 305, 640, 130, 35)
GUICtrlSetFont(-1, 10, 600, 0, "微软雅黑")
GUICtrlSetBkColor(-1, 0x9B59B6)
GUICtrlSetColor(-1, 0xFFFFFF)
Local $hExitBtn = GUICtrlCreateButton("退出", 450, 640, 130, 35)
GUICtrlSetFont(-1, 10, 600, 0, "微软雅黑")
GUICtrlSetBkColor(-1, 0xE74C3C)
GUICtrlSetColor(-1, 0xFFFFFF)
; 设置事件
GUICtrlSetOnEvent($hCollectBtn, "OnCollectInfo")
GUICtrlSetOnEvent($hSaveBtn, "OnSaveReport")
GUICtrlSetOnEvent($hSendBtn, "OnSendToServer")
GUICtrlSetOnEvent($hExitBtn, "OnExit")
; 设置窗口关闭事件
GUISetOnEvent($GUI_EVENT_CLOSE, "OnExit", $hMainGUI)
; 显示窗口
GUISetState(@SW_SHOW)
; 自动收集信息
OnCollectInfo()
; 消息循环
While 1
Sleep(100)
WEnd
GUIDelete($hMainGUI)
; 收集系统信息
Func OnCollectInfo()
GUICtrlSetData($hCollectBtn, "正在收集...")
GUICtrlSetState($hCollectBtn, $GUI_DISABLE)
; 收集基本信息
Local $sComputerName = @ComputerName
Local $sUserName = @UserName
Local $sOSVersion = GetOSVersion()
GUICtrlSetData($hComputerName, $sComputerName)
GUICtrlSetData($hUserName, $sUserName)
GUICtrlSetData($hOSVersion, $sOSVersion)
; 收集CPU和内存信息
CollectCPUAndMemory()
; 收集硬盘信息
CollectDiskInfo()
; 收集网络信息
CollectNetworkInfo()
; 收集显示器信息
CollectMonitorInfo()
GUICtrlSetData($hCollectBtn, "收集系统信息")
GUICtrlSetState($hCollectBtn, $GUI_ENABLE)
EndFunc
; 收集CPU和内存信息
Func CollectCPUAndMemory()
Local $sCPU = RegRead("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0", "ProcessorNameString")
If [url=home.php?mod=space&uid=209627]@Error[/url] Then
$sCPU = "未知"
EndIf
GUICtrlSetData($hCPUModel, $sCPU)
; 获取内存大小
Local $aMemInfo = MemGetStats()
Local $iTotalMemGB = Round($aMemInfo[1] / 1024 / 1024, 2)
GUICtrlSetData($hMemorySize, $iTotalMemGB & " GB")
; 获取操作系统安装日期
Local $sInstallDate = GetOSInstallDate()
GUICtrlSetData($hOSInstallDate, $sInstallDate)
EndFunc
; 收集硬盘信息
Func CollectDiskInfo()
Local $sDiskInfo = ""
; 使用bin目录下的smartctl工具
Local $sSmartctlExe = $sBinDir & "\smartctl.exe"
If Not FileExists($sSmartctlExe) Then
GUICtrlSetData($hDiskInfo, "错误: 找不到 smartctl.exe 工具")
Return
EndIf
; 创建临时文件保存硬盘信息
Local $sTempFile = @TempDir & "\disk_info_" & [url=home.php?mod=space&uid=597021]@year[/url] & [url=home.php?mod=space&uid=556771]@Mon[/url] & [url=home.php?mod=space&uid=501075]@Mday[/url] & "_" & @HOUR & @MIN & @SEC & ".txt"
Local $hTempFile = FileOpen($sTempFile, 2 + 8) ; 写入模式,UTF8
If $hTempFile = -1 Then
GUICtrlSetData($hDiskInfo, "错误: 无法创建临时文件")
Return
EndIf
FileWriteLine($hTempFile, "=== 硬盘信息收集 ===" & @CRLF)
FileWriteLine($hTempFile, "时间: " & @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF)
; 优先使用smartctl --scan获取设备列表(包含设备类型信息)
Local $iFoundCount = 0
Local $sScanOutput = ""
; 执行smartctl --scan
Local $sScanCmd = 'cmd /c cd /d "' & $sBinDir & '" && smartctl.exe --scan'
Local $iScanPID = Run($sScanCmd, "", @SW_HIDE, $STDOUT_CHILD + $STDERR_CHILD)
If Not @error Then
; 等待进程完成
While ProcessExists($iScanPID)
$sScanOutput &= StdoutRead($iScanPID)
If @error Then ExitLoop
Sleep(100)
WEnd
; 读取剩余输出
$sScanOutput &= StdoutRead($iScanPID)
EndIf
; 保存扫描结果到文件
If $sScanOutput <> "" Then
FileWriteLine($hTempFile, "=== smartctl --scan 输出 ===")
FileWriteLine($hTempFile, $sScanOutput)
FileWriteLine($hTempFile, @CRLF)
Else
FileWriteLine($hTempFile, "smartctl --scan 无输出或执行失败")
FileWriteLine($hTempFile, @CRLF)
EndIf
; 解析扫描结果
Local $aScannedDisks = ParseSmartctlScan($sScanOutput)
; 保存解析结果
If UBound($aScannedDisks) > 0 Then
FileWriteLine($hTempFile, "=== 解析到的设备数量: " & UBound($aScannedDisks) & " ===")
For $k = 0 To UBound($aScannedDisks) - 1
FileWriteLine($hTempFile, "设备 " & ($k + 1) & ": " & $aScannedDisks[$k][0] & " 类型: " & $aScannedDisks[$k][1])
Next
FileWriteLine($hTempFile, @CRLF)
Else
FileWriteLine($hTempFile, "未解析到设备")
FileWriteLine($hTempFile, @CRLF)
EndIf
; 对扫描到的每个设备获取详细信息
For $j = 0 To UBound($aScannedDisks) - 1
Local $sScannedPath = $aScannedDisks[$j][0]
Local $sScannedType = $aScannedDisks[$j][1]
FileWriteLine($hTempFile, "=== 正在获取设备信息: " & $sScannedPath & " (类型: " & $sScannedType & ") ===")
; 获取完整原始输出
Local $sFullOutput = GetDiskFullOutput($sScannedPath, $sScannedType)
If $sFullOutput <> "" Then
FileWriteLine($hTempFile, $sFullOutput)
FileWriteLine($hTempFile, @CRLF)
; 解析并显示到界面
Local $sParsedInfo = ParseDiskInfo($sFullOutput)
If $sParsedInfo <> "" Then
If $sDiskInfo <> "" Then $sDiskInfo &= @CRLF
$sDiskInfo &= "硬盘 " & ($iFoundCount + 1) & ": " & $sParsedInfo
$iFoundCount += 1
EndIf
Else
FileWriteLine($hTempFile, "无法获取该设备信息")
FileWriteLine($hTempFile, @CRLF)
EndIf
Next
; 如果扫描失败,尝试直接扫描PhysicalDrive0-9
If $iFoundCount = 0 Then
FileWriteLine($hTempFile, "=== 尝试直接扫描 PhysicalDrive ===")
For $i = 0 To 9
Local $sTestPath = "\\.\PhysicalDrive" & $i
FileWriteLine($hTempFile, "尝试: " & $sTestPath)
; 获取完整原始输出
Local $sFullOutput = GetDiskFullOutput($sTestPath)
If $sFullOutput <> "" Then
FileWriteLine($hTempFile, $sFullOutput)
FileWriteLine($hTempFile, @CRLF)
; 检查是否有有效信息
If StringInStr($sFullOutput, "Model Number") > 0 Or StringInStr($sFullOutput, "Device Model") > 0 Or StringInStr($sFullOutput, "Serial Number") > 0 Then
Local $sParsedInfo = ParseDiskInfo($sFullOutput)
If $sParsedInfo <> "" Then
If $sDiskInfo <> "" Then $sDiskInfo &= @CRLF
$sDiskInfo &= "硬盘 " & ($iFoundCount + 1) & ": " & $sParsedInfo
$iFoundCount += 1
EndIf
EndIf
EndIf
Next
EndIf
FileClose($hTempFile)
If $iFoundCount = 0 Then
$sDiskInfo = "未找到物理磁盘" & @CRLF & "请确保以管理员身份运行"
EndIf
GUICtrlSetData($hDiskInfo, $sDiskInfo)
EndFunc
; 解析硬盘信息(从完整输出中提取关键信息)
Func ParseDiskInfo($sFullOutput)
Local $sResult = ""
; 解析输出
Local $sModel = ExtractSmartctlValue($sFullOutput, "Device Model")
If $sModel = "" Then
$sModel = ExtractSmartctlValue($sFullOutput, "Model Family")
EndIf
If $sModel = "" Then
$sModel = ExtractSmartctlValue($sFullOutput, "Model Number")
EndIf
Local $sSerial = ExtractSmartctlValue($sFullOutput, "Serial Number")
If $sSerial = "" Then
$sSerial = ExtractSmartctlValue($sFullOutput, "Serial number")
EndIf
; 获取容量(支持多种格式)
Local $sCapacity = ExtractSmartctlValue($sFullOutput, "User Capacity")
If $sCapacity = "" Then
$sCapacity = ExtractSmartctlValue($sFullOutput, "Total NVM Capacity")
EndIf
If $sCapacity = "" Then
$sCapacity = ExtractSmartctlValue($sFullOutput, "Total capacity")
EndIf
; 格式化容量
Local $sFormattedCapacity = ""
If $sCapacity <> "" Then
; 支持 [1.02 TB] 格式
Local $aCapacityTB = StringRegExp($sCapacity, "\[(\d+\.?\d*)\s+TB\]", 1)
If @error = 0 And UBound($aCapacityTB) > 0 Then
Local $fTB = Number($aCapacityTB[0])
Local $iGB = Round($fTB * 1024, 2)
$sFormattedCapacity = $iGB & " GB"
Else
; 尝试 [bytes] 格式
Local $aCapacity = StringRegExp($sCapacity, "\[(\d+)\s+bytes\]", 1)
If @error = 0 And UBound($aCapacity) > 0 Then
Local $iBytes = Number($aCapacity[0])
Local $iGB = Round($iBytes / 1024 / 1024 / 1024, 2)
$sFormattedCapacity = $iGB & " GB"
Else
; 尝试其他格式
Local $aGB = StringRegExp($sCapacity, "(\d+\.?\d*)\s*GB", 1)
If @error = 0 And UBound($aGB) > 0 Then
$sFormattedCapacity = $aGB[0] & " GB"
Else
$sFormattedCapacity = $sCapacity
EndIf
EndIf
EndIf
EndIf
; 格式化显示:型号 | 序列号 | 大小
If $sModel <> "" Or $sSerial <> "" Or $sFormattedCapacity <> "" Then
Local $aParts[0]
If $sModel <> "" Then
ReDim $aParts[UBound($aParts) + 1]
$aParts[UBound($aParts) - 1] = "型号: " & $sModel
EndIf
If $sSerial <> "" Then
ReDim $aParts[UBound($aParts) + 1]
$aParts[UBound($aParts) - 1] = "序列号: " & $sSerial
EndIf
If $sFormattedCapacity <> "" Then
ReDim $aParts[UBound($aParts) + 1]
$aParts[UBound($aParts) - 1] = "大小: " & $sFormattedCapacity
EndIf
; 用 | 分隔
$sResult = _ArrayToString($aParts, " | ")
EndIf
Return $sResult
EndFunc
; 获取磁盘完整原始输出(用于调试)
Func GetDiskFullOutput($sDiskPath, $sDeviceType = "")
Local $sSmartctlExe = $sBinDir & "\smartctl.exe"
Local $sResult = ""
; 如果未指定设备类型,尝试不同的设备类型
Local $aDeviceTypes[5] = ["nvme", "sat", "ata", "scsi", ""]
; 如果指定了设备类型,优先使用
If $sDeviceType <> "" Then
$aDeviceTypes[0] = $sDeviceType
ReDim $aDeviceTypes[1]
EndIf
For $i = 0 To UBound($aDeviceTypes) - 1
Local $sCurrentType = $aDeviceTypes[$i]
Local $sCmd = ""
; 使用 -a 参数获取完整信息
If $sCurrentType = "" Then
$sCmd = 'cmd /c cd /d "' & $sBinDir & '" && smartctl.exe -a "' & $sDiskPath & '"'
Else
$sCmd = 'cmd /c cd /d "' & $sBinDir & '" && smartctl.exe -d ' & $sCurrentType & ' -a "' & $sDiskPath & '"'
EndIf
Local $iPID = Run($sCmd, "", @SW_HIDE, $STDOUT_CHILD + $STDERR_CHILD)
If @error Then ContinueLoop
Local $sOutput = ""
While ProcessExists($iPID)
$sOutput &= StdoutRead($iPID)
If @error Then ExitLoop
Sleep(100)
WEnd
; 读取剩余输出
$sOutput &= StdoutRead($iPID)
; 检查是否有错误
If StringInStr($sOutput, "Unable to detect device type") > 0 Or StringInStr($sOutput, "Device open failed") > 0 Then
ContinueLoop
EndIf
; 如果有任何输出,返回(用于调试)
If $sOutput <> "" Then
$sResult = "命令: " & $sCmd & @CRLF & @CRLF & $sOutput
ExitLoop
EndIf
Next
Return $sResult
EndFunc
; 解析smartctl --scan的输出
Func ParseSmartctlScan($sOutput)
Local $aResult[0][2] ; [设备路径, 设备类型]
If $sOutput = "" Then Return $aResult
; 按行分割
Local $aLines = StringSplit($sOutput, @CRLF, 1)
If @error Then
$aLines = StringSplit($sOutput, @LF, 1)
EndIf
For $i = 1 To $aLines[0]
Local $sLine = StringStripWS($aLines[$i], 3)
If $sLine = "" Then ContinueLoop
; 提取设备路径和类型
; 格式: /dev/sda -d nvme # /dev/sda, NVMe device
; 或者: \\.\PhysicalDrive0 -d nvme
; 使用正则表达式匹配:设备路径 可选-d 设备类型
Local $aMatch = StringRegExp($sLine, "^([^\s]+)(?:\s+-d\s+([^\s]+))?", 1)
If @error = 0 And UBound($aMatch) > 0 Then
Local $sDevice = StringStripWS($aMatch[0], 3)
Local $sDeviceType = ""
If UBound($aMatch) > 1 And $aMatch[1] <> "" Then
$sDeviceType = StringStripWS($aMatch[1], 3)
EndIf
; 如果是Windows路径格式,直接使用
If StringInStr($sDevice, "\\.\PhysicalDrive") > 0 Then
ReDim $aResult[UBound($aResult) + 1][2]
$aResult[UBound($aResult) - 1][0] = $sDevice
$aResult[UBound($aResult) - 1][1] = $sDeviceType
; 如果是Linux格式(/dev/sda),直接使用,smartctl支持
ElseIf StringInStr($sDevice, "/dev/") > 0 Then
ReDim $aResult[UBound($aResult) + 1][2]
$aResult[UBound($aResult) - 1][0] = $sDevice
$aResult[UBound($aResult) - 1][1] = $sDeviceType
EndIf
EndIf
Next
Return $aResult
EndFunc
; 从smartctl获取单个磁盘的详细信息
Func GetDiskInfoFromSmartctl($sDiskPath, $sDeviceType = "")
Local $sSmartctlExe = $sBinDir & "\smartctl.exe"
Local $sResult = ""
; 如果未指定设备类型,尝试不同的设备类型(NVMe、SATA、IDE等)
Local $aDeviceTypes[5] = ["nvme", "sat", "ata", "scsi", ""]
; 如果指定了设备类型,优先使用
If $sDeviceType <> "" Then
$aDeviceTypes[0] = $sDeviceType
ReDim $aDeviceTypes[1]
EndIf
For $i = 0 To UBound($aDeviceTypes) - 1
Local $sCurrentType = $aDeviceTypes[$i]
Local $sCmd = ""
; 使用 -a 参数获取完整信息(包括Model Number, Serial Number等)
If $sCurrentType = "" Then
; 不指定设备类型,让smartctl自动检测
$sCmd = '"' & $sSmartctlExe & '" -a "' & $sDiskPath & '"'
Else
; 指定设备类型
$sCmd = '"' & $sSmartctlExe & '" -d ' & $sCurrentType & ' -a "' & $sDiskPath & '"'
EndIf
Local $iPID = Run($sCmd, $sBinDir, @SW_HIDE, $STDOUT_CHILD)
If @error Then ContinueLoop
Local $sOutput = ""
While ProcessExists($iPID)
$sOutput &= StdoutRead($iPID)
If @error Then ExitLoop
Sleep(100)
WEnd
; 检查是否有错误
If StringInStr($sOutput, "Unable to detect device type") > 0 Or StringInStr($sOutput, "Device open failed") > 0 Or StringInStr($sOutput, "Read Device Identity failed") > 0 Then
ContinueLoop
EndIf
; 检查是否有有效信息(检查关键字段是否存在)
Local $bHasValidInfo = False
If StringInStr($sOutput, "Model Number") > 0 Or StringInStr($sOutput, "Device Model") > 0 Or StringInStr($sOutput, "Model Family") > 0 Then
$bHasValidInfo = True
EndIf
If StringInStr($sOutput, "Serial Number") > 0 Or StringInStr($sOutput, "Serial number") > 0 Then
$bHasValidInfo = True
EndIf
If StringInStr($sOutput, "Total NVM Capacity") > 0 Or StringInStr($sOutput, "User Capacity") > 0 Or StringInStr($sOutput, "Total capacity") > 0 Then
$bHasValidInfo = True
EndIf
If $bHasValidInfo Then
; 解析输出
Local $sModel = ExtractSmartctlValue($sOutput, "Device Model")
If $sModel = "" Then
$sModel = ExtractSmartctlValue($sOutput, "Model Family")
EndIf
If $sModel = "" Then
$sModel = ExtractSmartctlValue($sOutput, "Model Number")
EndIf
Local $sSerial = ExtractSmartctlValue($sOutput, "Serial Number")
If $sSerial = "" Then
$sSerial = ExtractSmartctlValue($sOutput, "Serial number")
EndIf
; 获取容量(支持多种格式)
Local $sCapacity = ExtractSmartctlValue($sOutput, "User Capacity")
If $sCapacity = "" Then
$sCapacity = ExtractSmartctlValue($sOutput, "Total NVM Capacity")
EndIf
If $sCapacity = "" Then
$sCapacity = ExtractSmartctlValue($sOutput, "Total capacity")
EndIf
; 如果至少有一个有效信息,返回结果
If $sModel <> "" Or $sSerial <> "" Or $sCapacity <> "" Then
If $sModel <> "" Then
$sResult &= " 型号: " & $sModel & @CRLF
EndIf
If $sSerial <> "" Then
$sResult &= " 序列号: " & $sSerial & @CRLF
EndIf
If $sCapacity <> "" Then
; 格式化容量 - 支持 [1.02 TB] 格式
Local $aCapacityTB = StringRegExp($sCapacity, "\[(\d+\.?\d*)\s+TB\]", 1)
If @error = 0 And UBound($aCapacityTB) > 0 Then
Local $fTB = Number($aCapacityTB[0])
Local $iGB = Round($fTB * 1024, 2)
$sResult &= " 大小: " & $iGB & " GB"
Else
; 尝试 [bytes] 格式
Local $aCapacity = StringRegExp($sCapacity, "\[(\d+)\s+bytes\]", 1)
If @error = 0 And UBound($aCapacity) > 0 Then
Local $iBytes = Number($aCapacity[0])
Local $iGB = Round($iBytes / 1024 / 1024 / 1024, 2)
$sResult &= " 大小: " & $iGB & " GB"
Else
; 尝试其他格式
Local $aGB = StringRegExp($sCapacity, "(\d+\.?\d*)\s*GB", 1)
If @error = 0 And UBound($aGB) > 0 Then
$sResult &= " 大小: " & $aGB[0] & " GB"
Else
$sResult &= " 大小: " & $sCapacity
EndIf
EndIf
EndIf
EndIf
; 找到有效信息,退出循环
ExitLoop
EndIf
EndIf
Next
Return $sResult
EndFunc
; 从smartctl输出中提取值
Func ExtractSmartctlValue($sOutput, $sKey)
; 尝试多种模式匹配
Local $aPatterns[3] = [$sKey & ":\s+(.+?)(?:\r\n|\r|\n)", $sKey & "\s+:\s+(.+?)(?:\r\n|\r|\n)", $sKey & ":\s+(.+?)$"]
For $i = 0 To UBound($aPatterns) - 1
Local $aMatches = StringRegExp($sOutput, $aPatterns[$i], 1)
If @error = 0 And UBound($aMatches) > 0 Then
Local $sValue = StringStripWS($aMatches[0], 3)
; 移除可能的注释部分(# 后面的内容)
Local $iCommentPos = StringInStr($sValue, " #")
If $iCommentPos > 0 Then
$sValue = StringLeft($sValue, $iCommentPos - 1)
EndIf
Return StringStripWS($sValue, 3)
EndIf
Next
Return ""
EndFunc
; 获取操作系统版本信息
Func GetOSVersion()
Local $sVersion = ""
; 获取Windows版本号
Local $sOSName = @OSVersion
Local $sArch = @OSArch
; 获取Windows版本名称(家庭版/专业版等)
Local $sEdition = ""
Local $oWMIService = ObjGet("winmgmts:\\.\root\cimv2")
If Not @error Then
Local $oOS = $oWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem")
For $oItem In $oOS
$sEdition = $oItem.Caption
; 提取版本信息,例如 "Microsoft Windows 11 家庭版" -> "Windows 11 家庭版"
Local $aMatch = StringRegExp($sEdition, "Windows\s+(\d+)\s*(.+)", 1)
If @error = 0 And UBound($aMatch) >= 2 Then
$sVersion = "Windows " & $aMatch[0] & " " & $aMatch[1]
Else
; 如果正则匹配失败,尝试简单提取
If StringInStr($sEdition, "Windows 11") > 0 Then
$sVersion = "Windows 11"
If StringInStr($sEdition, "家庭") > 0 Then
$sVersion &= " 家庭版"
ElseIf StringInStr($sEdition, "专业") > 0 Then
$sVersion &= " 专业版"
ElseIf StringInStr($sEdition, "企业") > 0 Then
$sVersion &= " 企业版"
ElseIf StringInStr($sEdition, "教育") > 0 Then
$sVersion &= " 教育版"
EndIf
ElseIf StringInStr($sEdition, "Windows 10") > 0 Then
$sVersion = "Windows 10"
If StringInStr($sEdition, "家庭") > 0 Then
$sVersion &= " 家庭版"
ElseIf StringInStr($sEdition, "专业") > 0 Then
$sVersion &= " 专业版"
ElseIf StringInStr($sEdition, "企业") > 0 Then
$sVersion &= " 企业版"
ElseIf StringInStr($sEdition, "教育") > 0 Then
$sVersion &= " 教育版"
EndIf
EndIf
EndIf
ExitLoop
Next
EndIf
; 如果无法获取,使用默认格式
If $sVersion = "" Then
$sVersion = $sOSName
EndIf
; 添加架构信息(去掉X)
Local $sArchClean = StringReplace($sArch, "X", "")
$sVersion &= " " & $sArchClean & "位"
Return $sVersion
EndFunc
; 获取操作系统安装日期
Func GetOSInstallDate()
Local $sInstallDate = "未知"
; 使用WMI获取操作系统安装日期
Local $oWMIService = ObjGet("winmgmts:\\.\root\cimv2")
If Not @error Then
Local $oOS = $oWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem")
For $oItem In $oOS
; 获取安装日期(WMI返回的是UTC时间戳,需要转换)
Local $sWMIInstallDate = $oItem.InstallDate
If $sWMIInstallDate <> "" Then
; 转换WMI日期格式:YYYYMMDDHHMMSS.FFFFFF+000 -> YYYY-MM-DD HH:MM:SS
Local $sYear = StringMid($sWMIInstallDate, 1, 4)
Local $sMonth = StringMid($sWMIInstallDate, 5, 2)
Local $sDay = StringMid($sWMIInstallDate, 7, 2)
Local $sHour = StringMid($sWMIInstallDate, 9, 2)
Local $sMinute = StringMid($sWMIInstallDate, 11, 2)
Local $sSecond = StringMid($sWMIInstallDate, 13, 2)
$sInstallDate = $sYear & "-" & $sMonth & "-" & $sDay & " " & $sHour & ":" & $sMinute & ":" & $sSecond
EndIf
ExitLoop
Next
EndIf
Return $sInstallDate
EndFunc
; 收集网络信息
Func CollectNetworkInfo()
Local $sMAC = ""
Local $sIP = ""
; 使用WMI获取网络适配器信息
Local $oWMIService = ObjGet("winmgmts:\\.\root\cimv2")
If @error Then
GUICtrlSetData($hMACAddress, "无法获取")
GUICtrlSetData($hIPAddress, "无法获取")
Return
EndIf
; 获取所有已连接的网络适配器(状态码2表示已连接)
Local $oAdapters = $oWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionStatus = 2 AND MACAddress IS NOT NULL")
For $oAdapter In $oAdapters
Local $sName = $oAdapter.Description
Local $sAdapterMAC = $oAdapter.MACAddress
; 跳过虚拟适配器
If StringInStr($sName, "Virtual") > 0 Or StringInStr($sName, "VMware") > 0 Or StringInStr($sName, "VirtualBox") > 0 Then
ContinueLoop
EndIf
; 跳过无效的MAC地址(全0或全F)
If $sAdapterMAC = "00:00:00:00:00:00" Or $sAdapterMAC = "FF:FF:FF:FF:FF:FF" Then
ContinueLoop
EndIf
; 获取IP地址
Local $sAdapterIP = ""
Local $oConfigs = $oWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index = " & $oAdapter.Index)
For $oConfig In $oConfigs
If IsObj($oConfig) And $oConfig.IPAddress <> "" Then
If IsArray($oConfig.IPAddress) Then
If UBound($oConfig.IPAddress) > 0 Then
; 优先获取IPv4地址
For $i = 0 To UBound($oConfig.IPAddress) - 1
If StringInStr($oConfig.IPAddress[$i], ":") = 0 Then ; 不是IPv6
$sAdapterIP = $oConfig.IPAddress[$i]
ExitLoop
EndIf
Next
If $sAdapterIP = "" And UBound($oConfig.IPAddress) > 0 Then
$sAdapterIP = $oConfig.IPAddress[0]
EndIf
EndIf
Else
$sAdapterIP = $oConfig.IPAddress
EndIf
EndIf
Next
; 使用第一个有效的适配器
If $sMAC = "" And $sAdapterMAC <> "" Then
$sMAC = $sAdapterMAC
EndIf
If $sIP = "" And $sAdapterIP <> "" Then
$sIP = $sAdapterIP
EndIf
; 如果已经找到MAC和IP,退出循环
If $sMAC <> "" And $sIP <> "" Then
ExitLoop
EndIf
Next
; 设置显示
If $sMAC = "" Then
GUICtrlSetData($hMACAddress, "未找到")
Else
GUICtrlSetData($hMACAddress, $sMAC)
EndIf
If $sIP = "" Then
GUICtrlSetData($hIPAddress, "未找到")
Else
GUICtrlSetData($hIPAddress, $sIP)
EndIf
EndFunc
; 收集显示器信息
Func CollectMonitorInfo()
Local $sMonitorInfo = ""
If Not FileExists($sMonitorDir & "\MonitorInfoView.exe") Then
GUICtrlSetData($hMonitorAutoInfo, "错误: 找不到 MonitorInfoView.exe")
Return
EndIf
; 运行MonitorInfoView获取活跃显示器,输出到临时目录
Local $sTempOutputDir = @TempDir & "\computer_info_output"
DirCreate($sTempOutputDir)
Local $sOutputFile = $sTempOutputDir & "\monitors.csv"
Local $sArgs = '/HideInactiveMonitors 1 /scomma "' & $sOutputFile & '"'
RunWait('"' & $sMonitorDir & "\MonitorInfoView.exe" & '" ' & $sArgs, $sMonitorDir, @SW_HIDE)
If Not FileExists($sOutputFile) Then
GUICtrlSetData($hMonitorAutoInfo, "无法获取显示器信息")
Return
EndIf
; 解析CSV文件
Local $aMonitors = ParseMonitorCSV($sOutputFile)
; 保存到全局变量
$aMonitorsInfo = $aMonitors
; 显示信息并填充到输入框
For $i = 0 To UBound($aMonitors) - 1
If $sMonitorInfo <> "" Then $sMonitorInfo &= @CRLF
$sMonitorInfo &= "显示器 " & ($i + 1) & ": " & $aMonitors[$i][0] & " | SN: " & $aMonitors[$i][1] & " | 大小: " & $aMonitors[$i][2]
; 显示器信息仅用于显示,不自动填充编号
Next
If $sMonitorInfo = "" Then
$sMonitorInfo = "未检测到活跃的显示器"
EndIf
GUICtrlSetData($hMonitorAutoInfo, $sMonitorInfo)
EndFunc
; 解析显示器CSV文件
Func ParseMonitorCSV($sFile)
Local $aResult[0][3]
Local $hFile = FileOpen($sFile, 0)
If $hFile = -1 Then Return $aResult
; 读取所有行
Local $sContent = FileRead($hFile)
FileClose($hFile)
If $sContent = "" Then Return $aResult
; 按行分割
Local $aLines = StringSplit($sContent, @CRLF, 1)
If @error Then
$aLines = StringSplit($sContent, @LF, 1)
EndIf
; 处理每一行
For $i = 1 To $aLines[0]
Local $sLine = $aLines[$i]
If $sLine = "" Then ContinueLoop
; 解析CSV行(处理引号内的逗号)
Local $aFields[20]
Local $iFieldCount = 0
Local $sCurrentField = ""
Local $bInQuotes = False
For $j = 1 To StringLen($sLine)
Local $sChar = StringMid($sLine, $j, 1)
If $sChar = '"' Then
$bInQuotes = Not $bInQuotes
ElseIf $sChar = "," And Not $bInQuotes Then
If $iFieldCount < UBound($aFields) Then
$aFields[$iFieldCount] = $sCurrentField
$iFieldCount += 1
$sCurrentField = ""
EndIf
Else
$sCurrentField &= $sChar
EndIf
Next
If $iFieldCount < UBound($aFields) Then
$aFields[$iFieldCount] = $sCurrentField
$iFieldCount += 1
EndIf
If $iFieldCount >= 3 Then
Local $sModel = StringStripWS($aFields[0], 3) ; 品牌型号
Local $sSN = StringStripWS($aFields[2], 3) ; 序列号
; 提取大小(通常在索引7或8的位置)
Local $sSize = ""
For $k = 7 To $iFieldCount - 1
If $k < $iFieldCount And $aFields[$k] <> "" Then
Local $sField = $aFields[$k]
; 查找包含英寸信息的字段
Local $aSizeMatch = StringRegExp($sField, "(\d+\.?\d*)\s*[英寸寸Ӣ]", 1)
If @error = 0 And UBound($aSizeMatch) > 0 Then
$sSize = $aSizeMatch[0] & "英寸"
ExitLoop
EndIf
EndIf
Next
If $sSize = "" And $iFieldCount > 7 Then
$sSize = StringStripWS($aFields[7], 3)
EndIf
; 清理大小字符串
$sSize = StringRegExpReplace($sSize, "[^0-9\.英寸寸]", "")
If StringInStr($sSize, "英寸") = 0 And StringInStr($sSize, "寸") = 0 Then
If $sSize <> "" Then $sSize &= "英寸"
EndIf
ReDim $aResult[UBound($aResult) + 1][3]
$aResult[UBound($aResult) - 1][0] = $sModel
$aResult[UBound($aResult) - 1][1] = $sSN
$aResult[UBound($aResult) - 1][2] = $sSize
EndIf
Next
Return $aResult
EndFunc
; 显示器数量改变事件
Func OnMonitorCountChange()
; 检查哪个单选按钮被选中
If GUICtrlRead($hMonitorCount1) = $GUI_CHECKED Then
$iMonitorCount = 1
GUICtrlSetState($hMonitor2Number, $GUI_HIDE)
GUICtrlSetState($hMonitor2NumberLabel, $GUI_HIDE)
Else
$iMonitorCount = 2
GUICtrlSetState($hMonitor2Number, $GUI_SHOW)
GUICtrlSetState($hMonitor2NumberLabel, $GUI_SHOW)
EndIf
EndFunc
; 保存报告
Func OnSaveReport()
; 验证必填项
Local $sDepartment = GUICtrlRead($hDepartment)
Local $sHostNumber = GUICtrlRead($hHostNumber)
Local $sResponsible = GUICtrlRead($hResponsible)
Local $sPurpose = GUICtrlRead($hPurpose)
Local $sMonitor1Number = GUICtrlRead($hMonitor1Number)
; 检查必填项
If $sDepartment = "" Then
MsgBox(48, "错误", "请填写使用部门!")
Return
EndIf
If $sHostNumber = "" Or $sHostNumber = "ZDBG02-" Then
MsgBox(48, "错误", "请填写电脑主机编号!")
Return
EndIf
If $sResponsible = "" Then
MsgBox(48, "错误", "请填写责任人!")
Return
EndIf
If $sPurpose = "" Then
MsgBox(48, "错误", "请填写用途!")
Return
EndIf
If $sMonitor1Number = "" Or $sMonitor1Number = "ZDBG01-" Then
MsgBox(48, "错误", "请填写显示器编号!")
Return
EndIf
Local $sReport = "电脑信息收集报告" & @CRLF
$sReport &= "==================" & @CRLF
$sReport &= "生成时间: " & @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF
; 系统信息
$sReport &= "【系统信息】" & @CRLF
$sReport &= "计算机名: " & GUICtrlRead($hComputerName) & @CRLF
$sReport &= "用户名: " & GUICtrlRead($hUserName) & @CRLF
$sReport &= "系统版本: " & GUICtrlRead($hOSVersion) & @CRLF
$sReport &= "CPU型号: " & GUICtrlRead($hCPUModel) & @CRLF
$sReport &= "内存总大小: " & GUICtrlRead($hMemorySize) & @CRLF
$sReport &= "操作系统安装日期: " & GUICtrlRead($hOSInstallDate) & @CRLF & @CRLF
; 硬盘信息
$sReport &= "【硬盘信息】" & @CRLF
$sReport &= GUICtrlRead($hDiskInfo) & @CRLF & @CRLF
; 网络信息
$sReport &= "【网络信息】" & @CRLF
$sReport &= "MAC地址: " & GUICtrlRead($hMACAddress) & @CRLF
$sReport &= "IP地址: " & GUICtrlRead($hIPAddress) & @CRLF & @CRLF
; 显示器信息
$sReport &= "【显示器信息】" & @CRLF
$sReport &= "显示器1编号: " & GUICtrlRead($hMonitor1Number) & @CRLF
If $iMonitorCount = 2 Then
$sReport &= "显示器2编号: " & GUICtrlRead($hMonitor2Number) & @CRLF
EndIf
$sReport &= @CRLF
; 显示器详细信息(从MonitorInfoView获取)
For $i = 0 To UBound($aMonitorsInfo) - 1
$sReport &= "显示器 " & ($i + 1) & " 详细信息: " & @CRLF
$sReport &= " 品牌型号: " & $aMonitorsInfo[$i][0] & @CRLF
$sReport &= " 序列号(SN): " & $aMonitorsInfo[$i][1] & @CRLF
$sReport &= " 尺寸: " & $aMonitorsInfo[$i][2] & @CRLF
$sReport &= @CRLF
Next
; 用户输入信息
$sReport &= "【用户输入信息】" & @CRLF
$sReport &= "电脑主机编号: " & GUICtrlRead($hHostNumber) & @CRLF
$sReport &= "使用部门: " & GUICtrlRead($hDepartment) & @CRLF
$sReport &= "责任人: " & GUICtrlRead($hResponsible) & @CRLF
$sReport &= "用途: " & GUICtrlRead($hPurpose) & @CRLF
; 获取部门和责任人信息
Local $sDepartment = GUICtrlRead($hDepartment)
Local $sResponsible = GUICtrlRead($hResponsible)
; 处理空值情况
If $sDepartment = "" Then $sDepartment = "未知部门"
If $sResponsible = "" Then $sResponsible = "未知责任人"
; 生成日期时间字符串
Local $sDateTime = @YEAR & @MON & @MDAY & "_" & @HOUR & @MIN & @SEC
; 保存文件到用户桌面,使用部门-责任人-日期时间.txt格式
Local $sDesktopDir = @DesktopDir
Local $sFileName = $sDesktopDir & "\" & $sDepartment & "-" & $sResponsible & "-" & $sDateTime & ".txt"
Local $hFile = FileOpen($sFileName, 2 + 8) ; 写入模式,UTF8
If $hFile <> -1 Then
FileWrite($hFile, $sReport)
FileClose($hFile)
MsgBox(64, "成功", "报告已保存到:" & @CRLF & $sFileName)
Else
MsgBox(48, "错误", "无法保存文件!")
EndIf
EndFunc
; 电脑主机编号输入事件
Func OnHostNumberChange()
Local $sCurrentText = GUICtrlRead($hHostNumber)
; 如果前缀被删除,自动添加回来
If StringLeft($sCurrentText, 7) <> "ZDBG02-" Then
Local $sCleanText = StringReplace($sCurrentText, "ZDBG02-", "")
GUICtrlSetData($hHostNumber, "ZDBG02-" & $sCleanText)
EndIf
EndFunc
; 显示器1编号输入事件
Func OnMonitor1NumberChange()
Local $sCurrentText = GUICtrlRead($hMonitor1Number)
; 如果前缀被删除,自动添加回来
If StringLeft($sCurrentText, 7) <> "ZDBG01-" Then
Local $sCleanText = StringReplace($sCurrentText, "ZDBG01-", "")
GUICtrlSetData($hMonitor1Number, "ZDBG01-" & $sCleanText)
EndIf
EndFunc
; 显示器2编号输入事件
Func OnMonitor2NumberChange()
Local $sCurrentText = GUICtrlRead($hMonitor2Number)
; 如果前缀被删除,自动添加回来
If StringLeft($sCurrentText, 7) <> "ZDBG01-" Then
Local $sCleanText = StringReplace($sCurrentText, "ZDBG01-", "")
GUICtrlSetData($hMonitor2Number, "ZDBG01-" & $sCleanText)
EndIf
EndFunc
; 发送到服务端
Func OnSendToServer()
; 获取服务端配置
Local $sServerIP = GUICtrlRead($hServerIP)
Local $sServerPort = GUICtrlRead($hServerPort)
; 验证配置
If $sServerIP = "" Or $sServerPort = "" Then
MsgBox(48, "错误", "请填写完整的服务端配置!")
Return
EndIf
; 验证必填项
Local $sDepartment = GUICtrlRead($hDepartment)
Local $sHostNumber = GUICtrlRead($hHostNumber)
Local $sResponsible = GUICtrlRead($hResponsible)
Local $sPurpose = GUICtrlRead($hPurpose)
Local $sMonitor1Number = GUICtrlRead($hMonitor1Number)
; 检查必填项
If $sDepartment = "" Then
MsgBox(48, "错误", "请填写使用部门!")
Return
EndIf
If $sHostNumber = "" Or $sHostNumber = "ZDBG02-" Then
MsgBox(48, "错误", "请填写电脑主机编号!")
Return
EndIf
If $sResponsible = "" Then
MsgBox(48, "错误", "请填写责任人!")
Return
EndIf
If $sPurpose = "" Then
MsgBox(48, "错误", "请填写用途!")
Return
EndIf
If $sMonitor1Number = "" Or $sMonitor1Number = "ZDBG01-" Then
MsgBox(48, "错误", "请填写显示器编号!")
Return
EndIf
; 直接生成报告内容,不保存到本地
Local $sReport = "电脑信息收集报告" & @CRLF
$sReport &= "==================" & @CRLF
$sReport &= "生成时间: " & @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF
; 系统信息
$sReport &= "【系统信息】" & @CRLF
$sReport &= "计算机名: " & GUICtrlRead($hComputerName) & @CRLF
$sReport &= "用户名: " & GUICtrlRead($hUserName) & @CRLF
$sReport &= "系统版本: " & GUICtrlRead($hOSVersion) & @CRLF
$sReport &= "CPU型号: " & GUICtrlRead($hCPUModel) & @CRLF
$sReport &= "内存总大小: " & GUICtrlRead($hMemorySize) & @CRLF
$sReport &= "操作系统安装日期: " & GUICtrlRead($hOSInstallDate) & @CRLF & @CRLF
; 硬盘信息
$sReport &= "【硬盘信息】" & @CRLF
$sReport &= GUICtrlRead($hDiskInfo) & @CRLF & @CRLF
; 网络信息
$sReport &= "【网络信息】" & @CRLF
$sReport &= "MAC地址: " & GUICtrlRead($hMACAddress) & @CRLF
$sReport &= "IP地址: " & GUICtrlRead($hIPAddress) & @CRLF & @CRLF
; 显示器信息
$sReport &= "【显示器信息】" & @CRLF
$sReport &= "显示器1编号: " & GUICtrlRead($hMonitor1Number) & @CRLF
If $iMonitorCount = 2 Then
$sReport &= "显示器2编号: " & GUICtrlRead($hMonitor2Number) & @CRLF
EndIf
$sReport &= @CRLF
; 显示器详细信息(从MonitorInfoView获取)
For $i = 0 To UBound($aMonitorsInfo) - 1
$sReport &= "显示器 " & ($i + 1) & " 详细信息: " & @CRLF
$sReport &= " 品牌型号: " & $aMonitorsInfo[$i][0] & @CRLF
$sReport &= " 序列号(SN): " & $aMonitorsInfo[$i][1] & @CRLF
$sReport &= " 尺寸: " & $aMonitorsInfo[$i][2] & @CRLF
$sReport &= @CRLF
Next
; 用户输入信息
$sReport &= "【用户输入信息】" & @CRLF
$sReport &= "电脑主机编号: " & GUICtrlRead($hHostNumber) & @CRLF
$sReport &= "使用部门: " & GUICtrlRead($hDepartment) & @CRLF
$sReport &= "责任人: " & GUICtrlRead($hResponsible) & @CRLF
$sReport &= "用途: " & GUICtrlRead($hPurpose) & @CRLF
; 获取文件名所需的信息
Local $sDepartment = GUICtrlRead($hDepartment)
Local $sResponsible = GUICtrlRead($hResponsible)
; 处理空值情况
If $sDepartment = "" Then $sDepartment = "未知部门"
If $sResponsible = "" Then $sResponsible = "未知责任人"
; 生成日期时间字符串
Local $sDateTime = @YEAR & @MON & @MDAY & "_" & @HOUR & @MIN & @SEC
; 生成文件名(仅用于发送,不保存到本地)
Local $sFileName = $sDepartment & "-" & $sResponsible & "-" & $sDateTime & ".txt"
; 发送请求
GUICtrlSetData($hSendBtn, "发送中...")
GUICtrlSetState($hSendBtn, $GUI_DISABLE)
; 禁用所有错误提示
Local $iOriginalErrorMode = Opt("ErrorMode", 2) ; 重定向错误到@error,不显示对话框
Local $bSentSuccessfully = False
; 尝试发送请求
Local $oHTTP = ObjCreate("WinHttp.WinHttpRequest.5.1")
If IsObj($oHTTP) Then
; 设置COM错误处理
ObjEvent($oHTTP, "HTTP_Error_")
; 定义请求URL
Local $sURL = "http://" & $sServerIP & ":" & $sServerPort & "/upload"
; 定义请求体
Local $sBoundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW"
Local $sContentType = "multipart/form-data; boundary=" & $sBoundary
Local $sBody = "--" & $sBoundary & @CRLF
$sBody &= "Content-Disposition: form-data; name=""file""; filename=""" & $sFileName & """" & @CRLF
$sBody &= "Content-Type: text/plain" & @CRLF & @CRLF
$sBody &= $sReport & @CRLF
$sBody &= "--" & $sBoundary & "--" & @CRLF
; 设置超时时间
$oHTTP.SetTimeouts(5000, 5000, 5000, 5000)
; 发送请求,使用严格的错误检查
Local $iError = 0
; 尝试打开连接
$oHTTP.Open("POST", $sURL, False)
If @error = 0 Then
; 设置请求头
$oHTTP.SetRequestHeader("Content-Type", $sContentType)
If @error = 0 Then
; 发送请求
$oHTTP.Send($sBody)
If @error = 0 Then
; 尝试获取状态码
Local $iStatus = 0
$iStatus = $oHTTP.Status
If @error = 0 And $iStatus = 200 Then
$bSentSuccessfully = True
EndIf
EndIf
EndIf
EndIf
; 释放对象
$oHTTP = 0
EndIf
; 恢复错误设置
Opt("ErrorMode", $iOriginalErrorMode)
; 显示结果
If $bSentSuccessfully Then
MsgBox(64, "成功", "发送成功")
Else
MsgBox(48, "错误", "发送失败,可能是服务端未响应或网络问题")
EndIf
GUICtrlSetData($hSendBtn, "发送到服务端")
GUICtrlSetState($hSendBtn, $GUI_ENABLE)
EndFunc
; 退出
Func OnExit()
; 删除临时目录和文件
Local $aTempDirs[4] ; 声明一个足够大的数组
; 填充数组
$aTempDirs[0] = @TempDir & "\bin"
$aTempDirs[1] = @TempDir & "\monitorinfoview"
$aTempDirs[2] = @TempDir & "\computer_info_output"
; 使用UBound遍历数组
For $i = 0 To 2 ; 只遍历我们填充的元素
If FileExists($aTempDirs[$i]) Then
; 尝试删除目录中的所有文件
FileDelete($aTempDirs[$i] & "\*.*")
; 尝试删除目录本身
DirRemove($aTempDirs[$i])
EndIf
Next
Exit
EndFunc
; HTTP错误处理函数(空实现,仅用于捕获COM对象错误)
Func HTTP_Error_()
; 空函数,用于捕获COM对象错误
; 不做任何处理,只是防止错误显示给用户
EndFunc
; 安全发送HTTP请求的包装函数
Func SendHttpRequest($oHTTP, $sURL, $sBody, $sContentType)
Local $bSuccess = False
; 确保对象有效
If Not IsObj($oHTTP) Then Return False
; 禁用错误提示
Local $iOriginalErrorMode = Opt("ErrorMode", 0)
; 尝试打开连接
$oHTTP.Open("POST", $sURL, False)
If Not @error Then
; 尝试设置超时时间
$oHTTP.SetTimeouts(5000, 5000, 5000, 5000)
If Not @error Then
; 尝试设置请求头
$oHTTP.SetRequestHeader("Content-Type", $sContentType)
If Not @error Then
; 尝试发送请求
$oHTTP.Send($sBody)
If Not @error Then
; 尝试获取状态码
Local $iStatus = $oHTTP.Status
If Not @error And $iStatus = 200 Then
$bSuccess = True
EndIf
EndIf
EndIf
EndIf
EndIf
; 恢复错误设置
Opt("ErrorMode", $iOriginalErrorMode)
Return $bSuccess
EndFunc