星期一,领导安排统计公司的计算机设备以便建立台账,领导的意思是录入到EXCEL表里再进行统计分析,可是这样的话,两个地方有200多台计算机,每台计算机都需要打开计算机设备信息进行核对录入,工作量不小,关键是这个星期就要见到统计数据。
用C#写无疑最快,在C#里用它本身的类、调用API、调用注册表都可以实现,问题是编译成可执行文件到XP、Win32位、Win64位的计算机上有些麻烦,为了尽快完成任务,安装了Powerbuilder 6.5和Ms Sql Server数据库,Powerbuilder 6.5可是15年前的编程工具了,忘得差不多了,折腾了3天,完成了信息收集和入库。
即将5个程序文件放到网上,通知单位人员下载运行,用户只需要输入用户名进入后点击【提取计算机信息】,然后保存就好了。
实现方法比较简单,首先在注册表里收集到具体的硬件信息,记录下来,然后在Powerbuilder去提取,这些除了内存和硬盘是用了API,其他的(显卡、网卡、IP地址、子网掩码、网关等信息)都是在注册表里提出来的,没有分写代码方便记录。
string S1,S2,SInfo,STEMP
long LBuf
long IFOR,I1
RegistryGet("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName","ComputerName",Regstring!,S1)
dw_1.setitem(dw_1.getrow(),"c05",S1)
//设备ID
RegistryGet("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\BIOS","SystemManufacturer",Regstring!,S1)
long retVal,a
ulong ll_retval
string ls_format = "0000",str,s_harddiskhex,s_harddiskhex_DB
integer i_len
n_cst_numerical my_hex
//取得SComputerDISKID
str = space(256)
ll_retval = GetVolumeInformationA("c:\", str, 256, RetVal, a, a, str, 256)
s_harddiskhex = my_hex.of_hex(retval)
If len(s_harddiskhex) > 4 then
i_len = len(s_harddiskhex) - 4
s_harddiskhex = upper(left(ls_format, 4 - i_len) + left(s_harddiskhex , i_len) + "-" + right(s_harddiskhex, 4))
End If
S1=S1+"||"+s_harddiskhex
dw_1.setitem(dw_1.getrow(),"c03",S1)
//计算机出厂型号
RegistryGet("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\BIOS","SystemProductName",Regstring!,S1)
dw_1.setitem(dw_1.getrow(),"c02",S1)
//操作系统
RegistryGet("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\","ProductName",Regstring!,S1)
//判断是32位还是64位系统
RegistryGet("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PROCESSOR_ARCHITECTURE",Regstring!,S2)
choose case S2
case "AMD64"
S2="64位"
case "x86"
S2="32位"
end choose
dw_1.setitem(dw_1.getrow(),"c07",S1+" ["+S2+"]")
/////////////////////////////////计算机的配置参数
//CPU
RegistryGet("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0","ProcessorNameString",Regstring!,S1)
SInfo=S1
S1=""
//硬盘信息
ulong L1,L2
RegistryGet("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Disk\Enum\","Count",REGuLong!,L1)
for L2=0 to L1 - 1
RegistryGet("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Disk\Enum\",string(L2),Regstring!,S1)
//去掉无用的信息
S1=right(S1,len(S1) - 14)
S1=left(S1,len(S1) - 20)
SInfo=S1+" //// "+SInfo
Next
//内存
strMemory strMemory1
decimal dec1
GlobalMemoryStatus(strMemory1)
dec1=(strMemory1.ultotalsize)/(1024*1024*1024)
dec1=dec1*2
S1=string(Round(dec1,0))+"G"
SInfo=S1+" |||| "+SInfo
//显卡
RegistryGet("HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\nvlddmkm\Device0","Device Description",Regstring!,S1)
SInfo=S1+" |||| "+SInfo
dw_1.setitem(dw_1.getrow(),"c04",SInfo)
//网络信息
String SSubkeylist[],SNetInfo[]
RegistryKeys("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\TCPIP\Parameters\Interfaces\",SSubkeylist)
for IFOR=1 to upperbound(SSubkeylist)
STEMP=SSubkeylist[IFOR]
//IP地址
RegistryGet("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\TCPIP\Parameters\Interfaces\"+STEMP,"IPAddress",RegMultiString!,SNetInfo)
dw_1.setitem(dw_1.getrow(),"c10",SNetInfo[1])
SNetInfo[1]=''
//子网掩码
RegistryGet("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\TCPIP\Parameters\Interfaces\"+STEMP,"SubnetMask",RegMultiString!,SNetInfo)
dw_1.setitem(dw_1.getrow(),"c11",SNetInfo[1])
SNetInfo[1]=''
//网关
RegistryGet("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\TCPIP\Parameters\Interfaces\"+STEMP,"DefaultGateway",RegMultiString!,SNetInfo)
S1=SNetInfo[1]
dw_1.setitem(dw_1.getrow(),"c12",SNetInfo[1])
if not ( IsNULL(S1) or S1="" ) then
goto Label1
end if
next
Label1:
//取最大值
select Max(c01) into :L1 from computerlist using XXSDB;
L1=L1+1
dw_1.setitem(dw_1.getrow(),"c01",L1)
datetime MyDT
MyDT=gf_getserverdatetime()
dw_1.setitem(dw_1.getrow(),"c17",MyDT)
dw_1.setitem(dw_1.getrow(),"c16",SServerUser)
API信息:
PUBLIC Subroutine GlobalMemoryStatus(ref strmemory lpBuffer) LIBRARY "kernel32.dll"
Function ulong GetVolumeInformationA ( string lpRootPathName , ref string pVolumeNameBuffer , long nVolumeNameSize , ref long lpVolumeSerialNumber , ref long lpMaximumComponentLength , ref long lpFileSystemFlags , ref string lpFileSystemNameBuffer , long nFileSystemNameSize ) Library "kernel32"
还有结构体声明:
最后就是编译为一个可执行文件,编译前一定做好备份,否则一点点的错误就会导致文件被破坏,比较麻烦。
发行的文件为绿色文件,没做安装包,总共5个文件包括可执行文件:CMIMS.exe、pbvm60.dll、pbmss60.dll、pbdwe60.dll、ntwdblib.DLL。目前,在WinXP、Win7-32位|64位、Win10的计算机上运行正常。
数据库是MS Sql Server 2000。