检查文件使用状态,不在使用中则直接覆盖目标文件。文件正在使用则先将目标文件重命名为临时文件,再复制源文件到目标文件,最后在重启后删除临时文件。
使用相关自定义函数:
;===============================================================================
; 说明: 检查文件是否正在使用
; 语法: _FileCheckInUse($sFile)
; 参数: $sFile - 源文件
; 需要: 无
; 返回: 成功 - 状态字符: In-Use, Not In-Use, Non-Existant, Read-Only
; 备注: 无
;===============================================================================
Func _FileCheckInUse($sFile)
Local $iDA = 0, $iSM = 0, $iCD = 0, $iFA = 0, $pSecurity = 0, $aResult
$iDA = 0xC0000000 ; GENERIC_READ + GENERIC_WRITE
$iCD = 3 ; OPEN_EXISTING
$iFA = 0x80 ; FILE_ATTRIBUTE_NORMAL
If FileExists($sFile) Then
If StringInStr(FileGetAttrib($sFile), "R") Then
Return "Read-Only"
Else
$aResult = DllCall("kernel32.dll", "hwnd", "CreateFile", "str", $sFile, "int", $iDA, "int", $iSM, "ptr", $pSecurity, "int", $iCD, "int", $iFA, "int", 0)
If @error OR $aResult[0] = 0xFFFFFFFF Then
Return "In-Use"
Else
DllCall("kernel32.dll", "int", "CloseHandle", "int", $aResult[0])
Return "Not In-Use"
EndIf
EndIf
Else
Return "Non-Existant"
EndIf
EndFunc ;==>_FileCheckInUse
;===============================================================================
; 说明: 在系统重启后移动/删除文件
; 语法: _FileMoveAtReboot($sSFile[, $sTFile = ""])
; 参数: $sSFile - 源文件
; $sTFile - [可选] 目标文件。如果不指定,文件将在重启后被删除
; 需要: 无
; 返回: 成功 - 1
; 失败 - 0, 并设置 @error 到
; 1 - 源文件不存在
; 2 - 权限不足。需要管理员组或 LocalSystem 帐户权限
; 3 - API 调用失败
; 备注: 源文件和目标文件必须在同一卷
;===============================================================================
Func _FileMoveAtReboot($sSFile, $sTFile = "")
Local $sRegTmp, $iDel, $aResult
$iDel = 0x5 ; MOVEFILE_REPLACE_EXISTING + MOVEFILE_DELAY_UNTIL_REBOOT
If NOT FileExists($sSFile) Then Return SetError(1, 0, 0)
$sRegTmp = "PendingFileRenameOperations" & Random(1000, 9999, 1)
RegWrite("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager", $sRegTmp, "REG_MULTI_SZ", "Test")
If @error Then Return SetError(2, 0, 0)
RegDelete("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager", $sRegTmp)
RegWrite("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager", "AllowProtectedRenames", "REG_DWORD", 1)
If $sTFile = "" Then
$aResult = DllCall("kernel32.dll", "int", "MoveFileEx", "str", $sSFile, "ptr", "", "dword", $iDel)
Else
$aResult = DllCall("kernel32.dll", "int", "MoveFileEx", "str", $sSFile, "str", $sTFile, "dword", $iDel)
EndIf
If @error OR $aResult[0] = 0 Then
Return SetError(3, 0, 0)
Else
Return 1
EndIf
EndFunc ;==>_FileMoveAtReboot
|