回复 1# 放羊的狼
说说我的做法
1. 共享文件夹中的一个ini文件记录了客户端软件版本的最新版本号
2. 客户端映射共享文件夹,检测版本号
3. 如果有新版本,下载新版本的客户端(我是用的FTP下载)
4. 删除客户端的自身程序,更名下载的更新软件。
具体可以参考的我的代码
#include <file.au3>
#include <array.au3>
#include <FTPEx.au3>
HotKeySet("^!q","_Myexit") ;设置ctrl+Alt+q热键,退出程序
Opt("TrayIconHide", 0)
Opt("TrayMenuMode",1)
;Opt("TrayIconDebug",1)
;=== To avoid multi-software running ===========================================================
$1 = ProcessExists("Swage Client.exe")
$list = ProcessList("Swage Client.exe")
For $i = 1 To $list[0][0]
If $list[$i][1] <> $1 Then Exit
Next
;===============================================================================================
If FileExists(@ScriptDir&'\updated.exe') Then FileDelete(@ScriptDir&'\updated.exe')
If FileExists(@ScriptDir&'\rst.bat') Then FileDelete(@ScriptDir&'\rst.bat')
If Not FileExists(@ScriptDir&'\WrongVersionAlarm.jpg') Then
FileInstall('D:\autoit3\my program\Swage\Swage Pin Count Monitor\WrongVersionAlarm.jpg',@ScriptDir&'\WrongVersionAlarm.jpg',1)
EndIf
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run","Swage Client.exe", "REG_SZ", @ScriptDir&"\Swage Client.exe")
Local $Timer1 = TimerInit(), $Timer1_diff ,$Timer2 = TimerInit(), $Timer2_diff ;初始化定时器
Global $PinCount = _GetPinCount()
Global $Socket_received,$Socket_send, $AddressArray_1 = "", $AddressArray_2 = ""
Global $MC_IP = @IPAddress1 ; 本机IP地址
If $MC_IP == "127.0.0.1" Then
$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
$colComputers = $objWMIService.ExecQuery("Select * from Win32_ComputerSystem")
$colComputers = $objWMIService.ExecQuery("Select * from Win32_ComputerSystem")
For $objItem In $colItems
$MC_IP = $objItem.IPAddress(0)
Next
EndIf
Local $mac = _API_Get_NetworkAdapterMAC ($MC_IP)
Global $Swage_version = FileGetVersion("c:\swage\swage.exe")
Global $MC_info[2]
_GetMCInfo()
Local $All_info = @ComputerName & '|' & $mac & '|' & $MC_IP & '|' & $Swage_version
Local $FTP_Server, $user, $Password,$FilePath, $Swage_version_base,$delayTime
If _MappingNetWorkDriver() = 1 Then
If $MC_info[0] <> "" Then IniWrite("x:\xms\Swage_Info.txt","M/C_Info",$MC_info[0],$All_info) ;记录机器信息到ocr001\xms\Swage_info.txt
$Swage_version_base = IniRead("x:\xms\config.txt","MC_Software_Rev","Swage","unknow")
$FTP_Server = IniRead("x:\xms\config.txt","Swage_FTP","SERVER","unknow")
$user = IniRead("x:\xms\config.txt","Swage_FTP","USERNAME","unknow")
$Password = IniRead("x:\xms\config.txt","Swage_FTP","PASSWORD","unknow")
$FilePath = IniRead("x:\xms\config.txt","Swage_FTP","FILE_PATH","unknow")
_DisconnectDriver()
EndIf
Global $Latest_version, $script_Version = FileGetVersion(@ScriptFullPath)
UDPStartup()
; 注册清理函数.
OnAutoItExitRegister("_Cleanup")
$Socket_received = UDPBind($MC_IP,65530) ;绑定本机的65530端口作为接受端口
$AddressArray_1 = _GetServerAddressArray() ;得到服务器端得IP地址列表
_SendMsg2Server()
While 1
$Timer1_diff = TimerDiff($Timer1)
If $Timer1_diff > 60000 Then
$AddressArray_2 = _GetServerAddressArray() ;得到服务器客户端IP地址列表和版本信息
If @error Then
$AddressArray_2 = ""
Else
If Not IsArray($AddressArray_1) Then
$AddressArray_1 = $AddressArray_2
_SendMsg2Server()
Else
If $AddressArray_2[0][0] <> $AddressArray_1[0][0] Then
$AddressArray_1 = $AddressArray_2
_SendMsg2Server()
Else
For $i = 1 To $AddressArray_2[0][0]
If $AddressArray_1[$i][0] <> $AddressArray_2[$i][0] Then ;如果2个数组内容不同
$AddressArray_1 = $AddressArray_2
_SendMsg2Server()
ExitLoop
EndIf
Next
$AddressArray_1 = $AddressArray_2
EndIf
EndIf
If $Latest_version <> "unknow" Then
$Return = _CompareVersion($script_Version,$Latest_Version)
If $Return = 1 Then
;MsgBox(0,"update","have a new revision")
$ret = _DownloadFileFromFTP($FTP_Server,$user,$Password,$FilePath,@ScriptName)
If Not @error Then
$ret = _UpdateSelf(@ScriptDir&'\updated.exe', @ScriptFullPath) ;自动更新软件
If $ret = 1 Then
_DisconnectDriver()
Exit
EndIf
EndIf
EndIf
EndIf
EndIf
_ReduceMemory(@AutoItPID)
$Timer1 = TimerInit()
_AlarmForWrongVersion()
EndIf
$Timer2_diff = TimerDiff($Timer2)
If $Timer2_diff > 10*60*1000 Then
_SendMsg2Server()
$delayTime = Random(1000,180000,1)
Sleep($delayTime)
_PinCountByMonth($PinCount)
$Timer2 = TimerInit()
;_ReduceMemory(@AutoItPID)
EndIf
$rData = UDPRecv($Socket_received,200) ;接受服务器信息
If $rdata <> "" Then
$SplitData = StringSplit($rdata,"|",1)
If Not @error Then
Switch $SplitData[0]
Case "update"
$FTP_Server1 = $SplitData[1]
$File_Path1 = $SplitData[2]
$user1 = $SplitData[3]
$Password1 = $SplitData[4]
$ret = _DownloadFileFromFTP($FTP_Server1,$user1,$Password1,$file_Path1,@ScriptName) ;下载更新软件到工作目录下temp里
If Not @error Then
$ret = _UpdateSelf(@ScriptDir&'\updated.exe', @ScriptFullPath) ;自动更新软件
If $ret = 1 Then Exit
EndIf
EndSwitch
EndIf
EndIf
;_ReduceMemory(@AutoItPID)
Sleep(100)
WEnd
;===========================================================
Func _Myexit()
Exit
EndFunc ; ==> _Myexit
;==得到swage pin的计数,如果成功,返回计数,如果失败,设置error 并返回-1===============================
Func _GetPinCount()
Local $temp1,$temp2,$Count,$openedFile
$openedFile = FileOpen("c:\Swage\PIN.CNT",0)
If $openedFile = -1 Then
Return SetError(-1,-1,-1)
Else
$temp1 = FileRead($openedFile)
If $temp1 <> "" Then
$temp2 = StringRegExp($temp1,'\d+',1)
If Not @error Then
$Count = $temp2[0]
Return $Count
EndIf
EndIf
EndIf
EndFunc ;==>_GetPinCount
;==获得包含机器ID和Cell ID的数组,成功返回 1,失败返回-1==================================
;==失败,$MC_info数组全为空值=============================================================
Func _GetMCInfo()
Local $fhwnd = FileOpen("c:\swage\swage.ini",0)
If $fhwnd = -1 Then
$MC_info[0] = ""
$MC_info[1] = ""
Return SetError(-1,-1,-1)
EndIf
Local $text = FileRead($fhwnd)
If Not @error Then
FileClose($fhwnd)
$temp = StringRegExp($text, 'MC_NUM=(\w+)',1 )
If Not @error Then
$MC_info[0]= $temp[0]
$MC_info[0] = StringStripWS($MC_info[0],8)
$MC_info[0] = StringUpper($MC_info[0])
Else
$MC_info[0] = ""
Return SetError(-1,-1,-1)
EndIf
$temp = StringRegExp($text, 'CELL_NUM=(\w+)',1 )
If Not @error Then
$MC_info[1]= $temp[0]
$MC_info[1] = StringStripWS($MC_info[1],8)
$MC_info[1] = StringUpper($MC_info[1])
Else
$MC_info[1] = ""
Return SetError(-1,-1,-1)
EndIf
Return 1
Else
$MC_info[0] = ""
$MC_info[1] = ""
Return SetError(-1,-1,-1)
EndIf
;If $iMachine_ID <> "unknow" Then
#CS If $iMachine_ID <> @ComputerName Then
MsgBox(48,"Warning","PC Name and Machine Name are mismatch," & @CRLF & "Please Call ME to check.")
Sleep(10000)
While 1
$iMachine_ID = IniRead("c:\swage\temp.ini","config","MC_NUM","unknow")
If $iMachine_ID <> @ComputerName Then
MsgBox(48,"Warning","PC Name and Machine Name are mismatch," & @CRLF & "Please Call ME to check.")
Else
ExitLoop
EndIf
Sleep(10000)
wend
EndIf
#CE
;Else
;SetError(-1,-1,)
EndFunc ;==>_MCidMatchPCName
;=============================================
Func _MappingNetWorkDriver()
Local $var = DriveGetDrive("Network") ;check if have network driver connected
If @error Then
$Map_Result = DriveMapAdd("X:","\\10.38.200.247\ocr001",0,"ocr001","")
Else
For $i = 1 To UBound($var)-1
If $Var[$i] = "X:" Then DriveMapDel($var[$i])
Next
$Map_Result = DriveMapAdd("X:","\\10.38.200.247\ocr001")
EndIf
If $Map_Result = 0 Then
;MsgBox(0,"Error","不能map ocr001网络盘。")
Return 0
Else
Return 1
endif
EndFunc ;==> _MappingNetWorkDriver
;===========================================================
Func _DisconnectDriver()
DriveMapDel("X:")
EndFunc ;==> _DisconnectDriver
Func _GetServerAddressArray()
Local $result = _MappingNetWorkDriver(),$Section
If $result = 0 Then
Return SetError(-1,-1,-1)
Else
$Latest_version = IniRead("x:\xms\config.txt","SOFT_VER","SWAGE_CLIENT","unknow")
Local $Section = IniReadSection("x:\xms\config.txt","Swage_Server")
If @error Then
_DisconnectDriver()
Return SetError(-1,-1,-1)
EndIf
_DisconnectDriver()
Return $Section
EndIf
EndFunc ;==>_GetServerAddressArray
;===断开UDP连接,释放端口 ===============================================================
Func _Cleanup()
UDPCloseSocket($Socket_received)
UDPShutdown()
EndFunc ;==>Cleanup
;=== Get the latest version software from FTP server ================
Func _DownloadFileFromFTP($iIP,$iUsername,$iPassword,$iFilePath,$iFilename)
Local $Open = _FTP_Open('MyFTP Control')
Local $Conn = _FTP_Connect($Open, $iIP, $iUsername, $iPassword, 0, "21")
If $conn Then
$File_Get = _FTP_FileGet($Conn,$iFilePath & "\" & $iFilename,@ScriptDir&"\updated.exe")
If Not @error Then
Return 1 ;下载成功
Else
Return SetError(-1, -1, 0) ;下载失败
EndIf
_FTP_Close($Conn)
Else
Return SetError(-1, -1, -1) ;FTP连接失败,返回值为-1,并设置Error为-1
EndIf
EndFunc ; ==> _DownloadFileFromFTP
;===============================================================================
; 说明: 退出后更新脚本自身
; 语法: _UpdateSelf($sFile[, $iDelay = 1[, $iResume = 0[, $sParm = ""]]])
; 参数: $sFile - 源更新文件
; $iDelay - [可选] 监视退出的间隔时间, 单位为秒
; $iResume - [可选] 更新后重新运行。0 - 不运行, 非0 - 重新运行
; $sParm - [可选] 重新运行命令行参数
; 需要: 无
; 返回: 成功 - 1
; 失败 - 0, 并设置 @error 到 1
; 备注: 无
;===============================================================================
#CS Func _UpdateSelf($sFile, $iDelay = 1, $iResume = 0, $sParm = "")
Local $CmdFile, $CmdCont
If NOT FileExists($sFile) Then Return SetError(1, 0, 0)
$iDelay = Int($iDelay)
If $iDelay < 1 Then $iDelay = 1
$CmdCont = 'attrib -r -s -h "' & @ScriptFullPath & '"' & @CRLF _
& ':loop' & @CRLF _
& 'ping -n ' & $iDelay + 1 & ' 127.0.0.1 > nul' & @CRLF _
& 'del "' & @ScriptFullPath & '"' & @CRLF _
& 'if exist "' & @ScriptFullPath & '" goto loop' & @CRLF _
& 'move /y "' & $sFile & '" "' & @ScriptFullPath & '"' & @CRLF
If $iResume Then
If $sParm = "" Then
$CmdCont &= '"' & @ScriptFullPath & '"' & @CRLF
Else
$CmdCont &= '"' & @ScriptFullPath & '" ' & $sParm & @CRLF
EndIf
EndIf
$CmdCont &= 'del %0' & @CRLF
$CmdFile = _TempFile(@TempDir, "~UPD", ".bat", 4)
FileWrite($CmdFile, $CmdCont)
Run($CmdFile, @TempDir, @SW_HIDE)
Return 1
EndFunc ;==>_UpdateSelf
#CE
;==整理内存==============================================================================
Func _ReduceMemory($i_PID = -1)
If $i_PID <> -1 Then
Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID)
Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0])
DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0])
Else
Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
EndIf
Return $ai_Return[0]
EndFunc ;==>_ReduceMemory
Func _SendMsg2Server()
$PinCount = _GetPinCount()
If IsArray($AddressArray_1) Then
For $i = 1 To $AddressArray_1[0][0]
If StringRegExp($AddressArray_1[$i][0],'10\.\d{2}\.\d{1,3}\.\d{1,3}',0) Then
$Socket_send = UDPOpen($AddressArray_1[$i][0],65529)
If Not @error Then
UDPSend($Socket_send,$MC_info[0] & "|" & $MC_IP & "|" & $PinCount & "|" & $Swage_Version & "|" & $script_Version & "|" & $MC_info[1])
UDPCloseSocket($Socket_send)
EndIf
EndIf
Next
EndIf
EndFunc ;==>_SendMsg2Server
;===============================================================================
; 说明: 退出后更新脚本自身
Func _UpdateSelf($newfile,$oldfile) ;$newfile欲更新的文件,含路径
If FileExists($newfile) Then
FileDelete(@TempDir & '\rst.bat')
FileWrite(@TempDir & '\rst.bat','attrib -r -s -h "' & @ScriptFullPath & '"' & @CRLF _
& 'ping 127.0.0.1 >nul' & @CRLF _
& 'copy /y ' & FileGetShortName($newfile)&' ' & FileGetShortName($oldfile) & @CRLF _
& FileGetShortName($oldfile) & @CRLF _
& 'echo by pcbar')
If Run(@TempDir & '\rst.bat', "", @SW_HIDE) = 0 Then
Return SetError(-1,-1,-1)
Else
Return 1
EndIf
EndIf
EndFunc
;==获取网卡物理地址==========================================================
Func _API_Get_NetworkAdapterMAC($sIP)
Local $iMAC, $MACSize
Local $i, $s, $r, $iIP
$iMAC = DllStructCreate("byte[6]")
$MACSize = DllStructCreate("int")
DllStructSetData($MACSize, 1, 6)
$r = DllCall("Ws2_32.dll", "int", "inet_addr", "str", $sIP)
$iIP = $r[0]
$r = DllCall("iphlpapi.dll", "int", "SendARP", "int", $iIP, "int", 0, "ptr", DllStructGetPtr($iMAC), "ptr", DllStructGetPtr($MACSize))
$s = ""
For $i = 0 To 5
If $i Then $s = $s & "-"
$s = $s & Hex(DllStructGetData($iMAC, 1, $i + 1), 2)
Next
Return $s
EndFunc ;==>_API_Get_NetworkAdapterMAC
;==软件版本比较和报警功能 ======================================================
Func _AlarmForWrongVersion()
$Swage_version = FileGetVersion("c:\swage\swage.exe")
If $Swage_version <> "unknow" And $Swage_version_base <> "unknow" And $Swage_version <> "0.0.0.0" Then
If $Swage_version <> $Swage_version_base Then
SplashImageOn("Wrong Swage Version Alarm",@ScriptDir&'\WrongVersionAlarm.jpg',-1,-1,-1,-1,16)
Sleep(60*1000)
SplashOff()
EndIf
EndIf
EndFunc ;==>_AlarmForWrongVersion
Func _CompareVersion($iCurrent_Version, $Base_Version) ;输入参数为2个版本号,前一个是当前版本号,后一个是基准版本号
Local $array_1, $array_2,$count_equal = 0
If StringRegExp($iCurrent_Version,'\b\d+\.\d+\.\d+\.\d+\b',0) And _ ;检查输入的2个版本号是否满足规则
StringRegExp($Base_Version,'\b\d+\.\d+\.\d+\.\d+\b',0) Then
$array_1 = StringSplit($iCurrent_Version,'.')
$array_2 = StringSplit($Base_Version,'.')
For $i = 1 To $array_1[0]
If Number($array_1[$i]) < Number($array_2[$i]) Then
Return 1 ; 返回1,说明当前版本号低于基准的版本号
ElseIf Number($array_1[$i]) = Number($array_2[$i]) Then
$count_equal += 1
Else
Return -1 ; 返回-1,说明当前版本号高于基准的版本号
EndIf
Next
If $count_equal = 4 Then Return 0 ;返回0,说明当前版本号等于于基准的版本号
Else
Return SetError(-1,-1,-2) ; 返回-2,并设置@error = -1,版本号格式错误
EndIf
EndFunc ;==>_CompareVersion
Func _PinCountByMonth($iPinCount)
Local $PinCountRecord, $pinCountTotal,$iSection = @YEAR & "-" & @MON,$round,$count_extra ,$last_PinCount
If _MappingNetWorkDriver() = 1 Then
If @MDAY = "01" And @HOUR = "00" And @MIN < 15 Then
$count_extra = $iPinCount ;新的一个月开始,得到上个月的多余的补数
IniWrite("x:\xms\Swage_Pin_Count_by_Month.txt", "Count_Extra", $MC_info[0],$count_extra)
EndIf
$last_PinCount = IniRead("x:\xms\Swage_Pin_Count_by_Month.txt", "Last_PinCount", $MC_info[0],"unknow")
If $last_PinCount = "unknow" Then IniWrite("x:\xms\Swage_Pin_Count_by_Month.txt", "Last_PinCount", $MC_info[0],0)
$count_extra = IniRead("x:\xms\Swage_Pin_Count_by_Month.txt", "Count_Extra", $MC_info[0],"unknow")
If $count_extra = "unknow" Then IniWrite("x:\xms\Swage_Pin_Count_by_Month.txt", "Count_Extra", $MC_info[0],0)
$PinCountRecord = IniRead("x:\xms\Swage_Pin_Count_by_Month.txt", $iSection, $MC_info[0],"unknow")
If $pinCountTotal = "unknow" Then IniWrite("x:\xms\Swage_Pin_Count_by_Month.txt", $iSection, $MC_info[0],0)
If $last_PinCount = $iPinCount Then ;如果pin计数前后两个相同
_DisconnectDriver()
Return ;不改变任何数据
EndIf
If Number($last_PinCount) > Number($iPinCount) Then
$last_PinCount = $iPinCount
$iPinCount += 50000
$pinCountTotal = Int(($PinCountRecord + $count_extra)/50000)*50000+$iPinCount-$count_extra
IniWrite("x:\xms\Swage_Pin_Count_by_Month.txt", $iSection, $MC_info[0],$pinCountTotal)
IniWrite("x:\xms\Swage_Pin_Count_by_Month.txt", "Last_PinCount", $MC_info[0],$last_PinCount)
Else
$last_PinCount = $iPinCount
$pinCountTotal = Int(($PinCountRecord + $count_extra)/50000)*50000+$iPinCount-$count_extra
IniWrite("x:\xms\Swage_Pin_Count_by_Month.txt", $iSection, $MC_info[0],$pinCountTotal)
IniWrite("x:\xms\Swage_Pin_Count_by_Month.txt", "Last_PinCount", $MC_info[0],$last_PinCount)
EndIf
_DisconnectDriver()
EndIf
EndFunc ;==>_PinCountByMonth
|