关于程序检测,防止重复运行的求助。[已解决]
本帖最后由 rhci 于 2017-9-25 09:52 编辑借鉴论坛下载更新代码,打包了一个基于web服务的更新软件,现在问题是,该软件如果重复运行,就会卡住,等待很久以后才会弹出报错窗口,并结束,求助,能否在代码里写入检测自身是否重复运行。源码共享如下:#NoTrayIcon
#Region ;**** 参数创建于 ACNWrapper_GUI ****
#PRE_Icon=C:\windows\system32\SHELL32.dll
#PRE_Outfile=upload.exe
#PRE_Outfile_x64=upload64.exe
#PRE_Compression=4
#PRE_Compile_Both=y
#PRE_UseX64=y
#PRE_Res_Comment=后台文件更新系统
#PRE_Res_Description=BIST-FILE-SYS
#PRE_Res_Fileversion=1.0.0.2
#PRE_Res_LegalCopyright=RX
#PRE_Res_requestedExecutionLevel=None
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
#include <WinAPI.au3>
#include <WinAPIProc.au3>
;~ #Include <Array.au3>
Global $UpSize = 0, $FlieSize, $aUpFile = [], $upme = False
Global $sUpUrl = IniRead("upload.ini", "Config", "up", "")
If FileExists(@ScriptDir & "\upload.ini") Then
Else
IniWrite(@ScriptDir & "\upload.ini", "Config", "up", "http://文件服务器IP/wmv/")
EndIf
GUICreate("正在下载最新资源", 240, 100)
GUICtrlCreateLabel("进度", 5, 13, 30, 20)
$progressbar1 = GUICtrlCreateProgress(35, 10, 200, 20)
$gxmsg = GUICtrlCreateLabel("正在读取更新文件...", 5, 43, 230, 50, 0x01)
GUISetState()
Local $hDownload = InetGet($sUpUrl & 'updata.ini', @TempDir & "\updata.ini", 16+1, 1);下载更新校验文件
Do
Sleep(250)
Until InetGetInfo($hDownload, 2) ; 检查下载是否完成.
Local $aData = InetGetInfo($hDownload);获取所有信息.
InetClose($hDownload);关闭句柄, 释放资源.
If $aData Then
;下载校验文件成功,分析校验数据
$gengxin = getcrc32()
If $gengxin <> '' Then
gengxin()
EndIf
FileDelete(@TempDir & "\updata.ini")
DirRemove (@ScriptDir & "\Rxtemp\")
Else
MsgBox(0,"", '更新文件失败,请检查并修改配置文件.')
ShellExecute("upload.ini", "", @ScriptDir, "edit");
EndIf
Func gengxin()
GUICtrlSetState($progressbar1, 16)
$updataname = StringSplit($gengxin, ',')
$zdx = MylBytes($UpSize)
$FlieSize_A = StringSplit($FlieSize, ',')
GUICtrlSetData($gxmsg, '更新文件总大小 ' & $zdx)
$gxbegin = TimerInit()
Local $yxz = 0, $nD = 5, $hDownload[$nD], $down[$nD], $nF = 1; $nD = (线程数),
For $i = 1 To $updataname Step $nD
$fdx = 0
For $j = 0 To $nD - 1
If $i + $j <= $updataname Then
$fdx += $FlieSize_A[$i + $j];InetGetSize($gxurl & $updataname[$i + $j])
$url = $sUpUrl & StringReplace($updataname[$i + $j], '\', '/')
$saveurl = @ScriptDir & "\Rxtemp\" & $updataname[$i + $j]
$saveurl_tmp = StringMid($saveurl, 1, StringInStr($saveurl, '\', 0, -1))
If Not FileExists($saveurl_tmp) Then DirCreate($saveurl_tmp)
$hDownload[$j] = InetGet($url, $saveurl, 1, 1)
$nF = $i
Else
$hDownload[$j] = ''
EndIf
Next
Do
For $t = Int(100 / $UpSize) To 100
Sleep(300)
$dif = TimerDiff($gxbegin)
$s = Round($dif / 1000)
For $j = 0 To $nD - 1
If $hDownload[$j] <> '' Then
$down[$j] = InetGetInfo($hDownload[$j], 0)
Else
$down[$j] = 0
EndIf
Next
$s1 = getsize($down) + $yxz
$s3 = Round($s1 / $s)
If $s3 < 0 Then $s3 = 0 & 'k'
$stime = Round(($UpSize - $s1) / ($s3))
If $stime < 0 Then $stime = ""
$t = ($s1 / $UpSize) * 100
GUICtrlSetData($progressbar1, $t)
GUICtrlSetData($gxmsg, '总计需要下载 ' & $zdx & @LF & '已经下载 ' _
& MylBytes($s1) & @LF & '下载速度 ' & MylBytes($s3) & '/s' & @LF & '剩余时间 ' & $stime & '秒')
If getsize($down) = $fdx Then ExitLoop
Next
Until getsize($down) = $fdx
For $j = 0 To $nD - 1
If $hDownload[$j] <> '' Then
$yxz += InetGetInfo($hDownload[$j], 0)
InetClose($hDownload[$j])
EndIf
Next
Next
If $nF < $updataname Then
For $i = $nF To $updataname
$fdx = $FlieSize_A[$i];InetGetSize($gxurl & $updataname[$i])
$url = $sUpUrl & StringReplace($updataname[$i], '\', '/')
$saveurl = @ScriptDir & "\Rxtemp\" & $updataname[$i]
$saveurl_tmp = StringMid($saveurl, 1, StringInStr($saveurl, '\', 0, -1))
If Not FileExists($saveurl_tmp) Then DirCreate($saveurl_tmp)
$shDownload = InetGet($url, $saveurl, 1, 1)
Do
For $t = Int((InetGetInfo($shDownload, 0) + $yxz) / $UpSize * 100) To 100
Sleep(300)
$dif = TimerDiff($gxbegin)
$s = Round($dif / 1000)
$s1 = InetGetInfo($shDownload, 0) + $yxz
$s3 = Round($s1 / $s)
If $s3 < 0 Then $s3 = 0 & 'k'
$stime = Round(($UpSize - $s1) / ($s3))
If $stime < 0 Then $stime = ""
$t = ($s1 / $UpSize) * 100
GUICtrlSetData($progressbar1, $t)
GUICtrlSetData($gxmsg, '总计需要下载 ' & $zdx & @LF & '已经下载 ' _
& MylBytes($s1) & @LF & '下载速度 ' & MylBytes($s3) & '/s' & @LF & '剩余时间 ' & $stime & '秒')
If InetGetInfo($shDownload, 0) = $fdx Then ExitLoop
Next
Until InetGetInfo($shDownload, 2)
$yxz = $yxz + (InetGetInfo($shDownload, 0))
InetClose($shDownload)
Next
EndIf
For $i = 1 To $updataname
If $updataname[$i] = 'rxsetup.exe' Then
$upme = True
Else
$move = FileMove(@ScriptDir & "\Rxtemp\" & $updataname[$i], @ScriptDir & "\" & $updataname[$i], 9)
If $move <> 1 Then
Exit MsgBox(0, '', $updataname[$i] & '文件下载失败!')
EndIf
EndIf
Next
GUICtrlSetData($gxmsg, '')
GUICtrlSetState($progressbar1, 32)
If $upme = True Then
GUICtrlSetData($gxmsg, '更新自身!')
Sleep(500)
Run(@ComSpec & ' /c ping 127.0.0.1 -n 1© ' & @ScriptDir & '\Rxtemp\rxsetup.exe ' & @ScriptFullPath & '&' & @ScriptFullPath & ' up&Del ' & @ScriptDir & '\Rxtemp\rxsetup.exe', @ScriptDir, @SW_HIDE)
Exit
Else
GUICtrlSetData($gxmsg, '自身更新成功!')
EndIf
EndFunc ;==>gengxin
Func getsize($Array)
Dim $size = 0
For $i = 0 To UBound($Array) - 1
$size += $Array[$i]
Next
Return $size
EndFunc
Func getcrc32()
Dim $file_crc32
$file = FileOpen(@TempDir & "\updata.ini", 0)
While 1
$Line = FileReadLine($file)
If @error = -1 Then ExitLoop
$filename = StringSplit($Line, '=')
If Not @error Then
$CheckCrc32 = StringSplit($filename, '|')
If Not @error Then
If $filename = 'rxsetup.exe' Then
$CRC32 = _CRC32ForFile(@ScriptName)
If $CRC32 <> $CheckCrc32 Then
$file_crc32 &= $filename & ","
$FlieSize &= $CheckCrc32 & ","
$UpSize += $CheckCrc32
EndIf
Else
$CRC32 = _CRC32ForFile($filename)
If $CRC32 <> $CheckCrc32 Then
$file_crc32 &= $filename & ","
$FlieSize &= $CheckCrc32 & ","
$UpSize += $CheckCrc32
EndIf
EndIf
EndIf
EndIf
WEnd
FileClose($file)
$FlieSize = StringTrimRight($FlieSize, 1)
Return StringTrimRight($file_crc32, 1)
EndFunc
Func MylBytes($lBytes)
If $lBytes < 1024 Then
Return ($lBytes & "b")
ElseIf $lBytes < 1048576 Then
Return Round($lBytes / 1024, 2) & "k"
ElseIf $lBytes < 536870912 Then
Return Round($lBytes / (1024 ^ 2), 2) & "M"
Else
Return Round($lBytes / (1024 ^ 3), 2) & "G"
EndIf
EndFunc ;==>_MylBytes
; #FUNCTION# ;===============================================================================
;
; Name...........: _CRC32ForFile
; Description ...: Calculates CRC32 value for the specific file.
; Syntax.........: _CRC32ForFile ($sFile)
; Parameters ....: $sFile - Full path to the file to process.
; Return values .: Success - Returns CRC32 value in form of hex string
; - Sets @error to 0
; Failure - Returns empty string and sets @error:
; |1 - CreateFile function or call to it failed.
; |2 - CreateFileMapping function or call to it failed.
; |3 - MapViewOfFile function or call to it failed.
; |4 - RtlComputeCrc32 function or call to it failed.
; Author ........: trancexx
;
;==========================================================================================
Func _CRC32ForFile($sFile)
Local $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFileW", _
"wstr", $sFile, _
"dword", 0x80000000, _ ; GENERIC_READ
"dword", 1, _ ; FILE_SHARE_READ
"ptr", 0, _
"dword", 3, _ ; OPEN_EXISTING
"dword", 0, _ ; SECURITY_ANONYMOUS
"ptr", 0)
If @error Or $a_hCall = -1 Then
Return SetError(1, 0, "")
EndIf
Local $hFile = $a_hCall
$a_hCall = DllCall("kernel32.dll", "ptr", "CreateFileMappingW", _
"hwnd", $hFile, _
"dword", 0, _ ; default security descriptor
"dword", 2, _ ; PAGE_READONLY
"dword", 0, _
"dword", 0, _
"ptr", 0)
If @error Or Not $a_hCall Then
DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
Return SetError(2, 0, "")
EndIf
DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
Local $hFileMappingObject = $a_hCall
$a_hCall = DllCall("kernel32.dll", "ptr", "MapViewOfFile", _
"hwnd", $hFileMappingObject, _
"dword", 4, _ ; FILE_MAP_READ
"dword", 0, _
"dword", 0, _
"dword", 0)
If @error Or Not $a_hCall Then
DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
Return SetError(3, 0, "")
EndIf
Local $pFile = $a_hCall
Local $iBufferSize = FileGetSize($sFile)
Local $a_iCall = DllCall("ntdll.dll", "dword", "RtlComputeCrc32", _
"dword", 0, _
"ptr", $pFile, _
"int", $iBufferSize)
If @error Or Not $a_iCall Then
DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
Return SetError(4, 0, "")
EndIf
DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
Local $iCRC32 = $a_iCall
Return SetError(0, 0, Hex($iCRC32))
EndFunc ;==>_CRC32ForFile
回复 1# rhci _Singleton
回复 2# yamakawa
...加哪里?怎么弄?举个栗子呗 回复 3# rhci
照搬帮助文件的例子#include <Misc.au3>
#include <MsgBoxConstants.au3>
If _Singleton("test", 1) = 0 Then
MsgBox($MB_SYSTEMMODAL, "警告", "本程序已经在运行!")
Exit
EndIf
MsgBox($MB_SYSTEMMODAL, "OK", "成功启动!")
回复 4# yamakawa
好吧,大神,告诉我,我应该怎么加入到我上面的代码里? 回复 4# yamakawa
谢了大神,搞定了 回复 6# rhci
注意版規 搞定了 請修改標題
页:
[1]