Jump to content

Close file handles on Server to replace a file with a new version


rudi
 Share

Recommended Posts

Hello,

When new versions e.g. of your compiled script cannot be replaced on the server, as they are in use, you can use this script to manage to close the open handles and to replace the old file with your new version.

image.png.715aa9a25edfb1ed545174274aa052f6.png

; Autoit v3.3.14.5
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_Description=Close OpenFileHandlles, replace file on Server with a new version
#AutoIt3Wrapper_Res_Fileversion=1
#AutoIt3Wrapper_Res_LegalCopyright=(c) 2019 by Rudolf Thilo, IT-Beratung Rudolf Thilo
#AutoIt3Wrapper_Res_SaveSource=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <NetShare.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <EditConstants.au3>
; Enumerate open files on the server


$DragDropOpenFile = "<drag-drop file locked on Server to be closed and replaced>"
$DragDropNewFile = "<drag-drop file to replace the one on the server>"
$NewFile = ""
$Gui_h = 250
$Gui_w = 800
$vDist = 7
; GUICreate($GuiTitle, $w, $h, @DesktopWidth - $w - 100, @DesktopHeight - $h - 60, -1, $WS_EX_ACCEPTFILES) ; generally enable drag-drop for files into other GUI controls
$myGui = GUICreate("force close of all NETWORK opened file handles", $Gui_w, $Gui_h, 100, 100, -1, $WS_EX_ACCEPTFILES)

$InputFileToClose = GUICtrlCreateInput($DragDropOpenFile, 20, $vDist, $Gui_w - 40, 20)
GUICtrlSetState(-1, $GUI_DROPACCEPTED) ; allow drag-droping files for this control, $InputFile
Opt("Guicoordmode", 2)
$InputFileNew = GUICtrlCreateInput($DragDropNewFile, -1, $vDist)
GUICtrlSetState(-1, $GUI_DROPACCEPTED) ; allow drag-droping files for this control, $InputFile
GUICtrlSetState(-1, $GUI_DISABLE)
$lServer = GUICtrlCreateLabel("<server>", -1, $vDist)
$lShare = GUICtrlCreateLabel("<share>", -1, $vDist)
$lPath = GUICtrlCreateLabel("<path>", -1, $vDist)
$lFile = GUICtrlCreateLabel("<file>", -1, $vDist)

$doit = GUICtrlCreateButton("search for and close open file handles", -1, $vDist)
GUICtrlSetState(-1, $GUI_DISABLE)
$exit = GUICtrlCreateButton("cancel", -1, $vDist)



GUISetState()



$FN = False
$FNnew = ""
$FNmatch = False
$ToolTitle = ""
$ToolTxt = ""



While 1
    $input = GUICtrlRead($InputFileToClose)
    If $input <> $DragDropOpenFile Then ; da wurde was reingezogen
        $DragDropOpenFile = $input
        If StringLeft($input, 2) = "\\" Then
            $Type = "UNC"
            $ServerShareUNC = StringLeft($input, StringInStr($input, "\", 0, 4) - 1)
            $fRelPathFN = StringReplace($input, $ServerShareUNC, "")
            $fPath = StringLeft($fRelPathFN, StringInStr($fRelPathFN, "\", 0, -1))
            $FN = StringTrimLeft($fRelPathFN, StringInStr($fRelPathFN, "\", 0, -1))
        ElseIf StringMid($input, 2, 1) = ":" Then ; Pfad mit Laufwerksbuchstabe, evtl. Netzwerk Mapping (erforderlich)
            $drive = StringLeft($input, 2)
            $Type = DriveGetType($drive)
            If $Type = "Network" Then
                $ServerShareUNC = DriveMapGet($drive)
                $foo = StringReplace($input, $drive, $ServerShareUNC) ; Laufwerkspfad in UNC Pfad umwandeln
                $fRelPathFN = StringReplace($foo, $ServerShareUNC, "")
                $fPath = StringLeft($fRelPathFN, StringInStr($fRelPathFN, "\", 0, -1))
                $FN = StringTrimLeft($fRelPathFN, StringInStr($fRelPathFN, "\", 0, -1))
            Else
                MsgBox(0, @ScriptLineNumber, "This script can *ONLY* close open file handles on NETWORK SHARES!" & @CRLF & _
                        $input & @CRLF & _
                        $drive & " = " & $Type)
                ContinueLoop 2
            EndIf
        EndIf
        $Server = StringLeft($ServerShareUNC, StringInStr($ServerShareUNC, "\", 0, 3) - 1)
        $Share = StringTrimLeft($ServerShareUNC, StringInStr($ServerShareUNC, "\", 0, 3) - 1)
        GUICtrlSetData($lServer, $Server)
        GUICtrlSetData($lShare, $Share)
        GUICtrlSetData($lPath, $fPath)
        GUICtrlSetData($lFile, $FN)
        GUICtrlSetState($doit, $GUI_ENABLE)
        GUICtrlSetState($InputFileNew, $GUI_ENABLE)
    EndIf

    If $NewFile <> GUICtrlRead($InputFileNew) Then
        $NewFile = GUICtrlRead($InputFileNew)
        If $NewFile <> $DragDropNewFile Then
            If StringInStr($NewFile, $DragDropNewFile) Then
                $NewFile = StringReplace($NewFile, $DragDropNewFile, "")
                GUICtrlSetData($InputFileNew, $NewFile)
            EndIf
            $FNnew = StringTrimLeft($NewFile, StringInStr($NewFile, "\", 0, -1))
            If $FN = $FNnew Then
                If $FNmatch = False Then
                    $FNmatch = True
                    GUICtrlSetData($doit, "Search for open file handles, close them, overwrite old file.")
                EndIf
            Else
                If $FNmatch Then
                    $FNmatch = False
                    GUICtrlSetData($doit, "Search for open file handles and close them.")
                    GUICtrlSetData($InputFileNew,$DragDropNewFile)
                EndIf
            EndIf
        EndIf
    EndIf
    Switch GUIGetMsg()
        Case $exit, $GUI_EVENT_CLOSE
            GUIDelete($myGui)
            Exit
        Case $doit
            AbArbeiten($Server, $Share, $fPath, $FN)
    EndSwitch
WEnd





Func AbArbeiten($_Srv, $_Shr, $_fPth, $_fNme)

    Local $iID = 0
    Local $iRights = 1
    Local $iLckCount = 2
    Local $iFPFN = 3
    Local $iUser = 4

    ConsoleWrite($_fPth & $_fNme & @CRLF)

    Local $aFile = _Net_Share_FileEnum($_Srv)
    If IsArray($aFile) Then
        ; _ArrayDisplay($aFile)
        Local $x
        $ToolTxt = "Open Handles:"
        $ToolTitle =  $aFile[0][0] & " handles still waiting to be checkt..."
        UpdateToolTip()
        AdlibRegister(UpdateToolTip, 1000)
        For $x = $aFile[0][0] To 1 Step -1
            $ToolTitle = $x & " handles waiting to be checked..."

            If Not StringInStr($aFile[$x][$iFPFN], $_fPth & $_fNme) Then
                ; ConsoleWrite("Nix Enthalten in: " & $aFile[$x][$iFPFN] & @CRLF)
                _ArrayDelete($aFile, $x)
            Else
                $ToolTxt &= @CRLF & $aFile[$x][$iFPFN] & ", User = " & $aFile[$x][$iUser]
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ToolTxt = ' & $ToolTxt & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
            EndIf
        Next
        $aFile[0][0] = UBound($aFile) - 1
        _ArraySort($aFile, 0, 1, 0, $iUser)
        ; _ArrayDisplay($aFile, $aFile[0][0] & " FileLocks found.")
        If $aFile[0][0] = 0 Then
            $ToolTitle = "Done. No open handles coud be found."
            $ToolTxt &= @CRLF & "Nothing to be closed!"
            Sleep(2000)
            $ToolTxt = ""
        Else
            $ToolTitle = $aFile[0][0] & " Handles found to be closed..."
            $CloseErr = 0
            For $x = 1 To $aFile[0][0]
                If _Net_Share_FileClose($Server, $aFile[$x][$iID]) Then
                    $ToolTxt &= @CRLF & @TAB & "Handle closed: " & $aFile[$x][$iID]
                Else
                    $ToolTxt &= @CRLF & "ERROR: Handle Close Failed! --> " & $aFile[$x][$iFPFN] & ", User = " & $aFile[$x][$iUser]
                    $CloseErr += 1
                EndIf
            Next
            ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $CloseErr = ' & $CloseErr & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
            If $CloseErr = 0 Then
                $ToolTitle = "Alle open handles were closed successfully."
                If FileExists($NewFile) Then
                    If FileCopy($NewFile, $input, 1 + 8) Then
                        $ToolTitle = "File could be replaced."
                        $ToolTxt = "done"
                    Else
                        $ToolTitle = "File could *NOT* be replaced"
                        $ToolTxt = "Most propably a newly open file handle was created while this script was running." & @CRLF & _
                                "Just start over again."
                    EndIf
                EndIf
            Else
                $ToolTitle = $CloseErr & " handles could *NOT* be closed!"
                Sleep(2000)
            EndIf
            Sleep(1000)
            $ToolTxt = ""
            $ToolTitle = ""
        EndIf
    Else
        MsgBox(0, "not an array", $aFile & @CRLF & @error & @CRLF & @extended)
    EndIf
EndFunc   ;==>AbArbeiten


Func UpdateToolTip()
    ToolTip($ToolTxt, MouseGetPos(0) + 20, MouseGetPos(1) + 20, $ToolTitle)
    ; ConsoleWrite( $ToolTxt & @CRLF & $ToolTitle & @CRLF & "-------------------" & @CRLF)
EndFunc   ;==>UpdateToolTip

Rudi.

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...