Andlin Posted November 17, 2011 Share Posted November 17, 2011 I have a long script that at the end i want to rename a file to overwrite a file used earlier. however it fails. I am guessing that there is a fileopen handle sitting somewhere associated to the file. I understand that the FileMove("source", "Destination", 1) will perform the following steps 1. if destination exists then delete it. 2. rename the source to the destination. however if the destination is open then it will fail on both steps, but once the application exit's the file handles are all then released and step 1 will complete, but step 2 doesnt happen. I have searched my code for where i may have forgotten to fileclose the destination but am unable to find it. Is there a way to report back the current handles that are open? #include<File.au3> Dim $sFile Dim $Content Dim $counter $sFile = FileOpen("Test.txt",1) for $counter = 1 to 10 FileWriteLine($sFile, "This should be in test2") Next FileClose($sFile) $sFile = FileOpen("Test2.txt",1) for $counter = 1 to 10 FileWriteLine($sFile, "This shouldn't be here") Next FileClose($sFile) ;Leave file open and try to move while open. $sFile = FileOpen("Test2.txt",1) FileMove("test.txt", "test2.txt",1) MsgBox(0,"Check", "Check if file has moved/renamed") Exit in the code above if i remove line 21 then it works as it should but with line 21 in it is an example of a handle left open. Cheers Link to comment Share on other sites More sharing options...
Varian Posted November 17, 2011 Share Posted November 17, 2011 There are numerous posts about this around the forum...search for "FileInUse". Here is a quick function This will allow you to loop until the file is able to be overwritten, or at least report that the file is open. Link to comment Share on other sites More sharing options...
Andlin Posted November 17, 2011 Author Share Posted November 17, 2011 I know how to tell if a file is in use. However this will not tell me what the filehandle is that has it open so that i can close it. Thanks for your effort though. Cheers Link to comment Share on other sites More sharing options...
Varian Posted November 17, 2011 Share Posted November 17, 2011 Have you checked out "handle.exe" from PSTools? The syntax that you would use would be:handle.exe - "yourfilename.txt"This would return the PID from your AutoIT Script...however, if you are using a single script, you may do well to:if file is in use, create a temp batch script to do your rename/file moveExit & run your batch scriptIn your example code, I only saw 20 lines...what line did you remove to make it fail? Link to comment Share on other sites More sharing options...
Andlin Posted November 18, 2011 Author Share Posted November 18, 2011 Thanks. The script as it is above should fail due to line 17. the handle.exe wont help as it will (as you stated) just give me the pid of the exe that i am working in. I like your idea of a batch script, although one thing springs to mind, if i put a delay in the batch script to allow main exe to complete, will the main exe run the batch script and exit before checking that the batch is complete. Basically if i have:- run("temp.bat") exit will exit happen while temp.bat is still running, or does it wait until temp.bat is complete before it moves to the next line which is to exit the exe? of course i can write a quick script to check this, but thought i would be lazy and ask Cheers Link to comment Share on other sites More sharing options...
Andlin Posted November 18, 2011 Author Share Posted November 18, 2011 FWIW i just tested it with the following script replacing the section above and it does start the batch file then exit the app prior to the batch file compleing. ;Leave file open and try to move while open. $sFile = FileOpen("Test2.txt",1) FileDelete("rename.bat") $sFile2 = FileOpen("rename.bat",1) FileWriteLine($sFile2,"ECHO Off") FileWriteLine($sFile2,"ping 127.0.0.2") ;This is simply creating some time to allow the current exe to exit before the batch tries to rename the file. FileWriteLine($sFile2,"del test2.txt") FileWriteLine($sFile2,"rename test.txt test2.txt") ;~ FileWriteLine($sFile2,"Pause") FileClose($sFile2) run("rename.bat", "", @SW_HIDE) Exit Cheers Link to comment Share on other sites More sharing options...
Varian Posted November 19, 2011 Share Posted November 19, 2011 You can call the Exit Function with "Run("Some Program") as it's parameters: Exit 1 ;Exit with Code 1 OR Exit Run('calc.exe') ;Exit with Code "Run Calc.exe" Here is an example of creating a pseudo-dynamic batch file that will wait for your script to end before continuing. In this script, the batch file sits around and waits for the PID that is passed to it to no longer exist...Then it renames the Sciptfile that spawned it (impossible to do while the script is running), then renames is back to its' original name. This is just one of those other ways to get around your problem. expandcollapse popupLocal $iCounter = 0 Local $iPID = @AutoItPID, $ScriptName = @ScriptFullPath, $NewName = @ScriptDir & 'NewName.' & StringRegExpReplace(@ScriptName, '^.+.', '') Local $sWidth = @DesktopWidth / 4 Local $sHeight = 25 Local $sX = (@DesktopWidth / 2) - ($sWidth / 2) Local $sY = (@DesktopHeight / 2) - ($sHeight / 2) ;Splash to let you know that the Scipt is Still running $iSplash = SplashTextOn('', @ScriptName & ' is now running', $sWidth, $sHeight, $sX, $sY, 49, '', 14) While 1 If Not $iCounter Then ;Sent paramters: This Scripts' PID, Then FQN Of This Script, The FQN of the New Filename _SelfRenameBatch($iPID & ' "' & $ScriptName & '" "' & $NewName & '"') EndIf If $iCounter >= 6 Then ExitLoop Sleep(1000) ;Update The Splash Text When inside the Loop ControlSetText($iSplash, '', 'Static1', 'Now in Loop # ' & $iCounter) $iCounter += 1 WEnd ControlSetText($iSplash, '', 'Static1', 'Script Is Now Exiting!!') Sleep(1500) Exit Func _SelfRenameBatch($iParameters = '') Local $wString, $hFile, $sTempFile = @TempDir & 'TempBatch.cmd' $wString &= '@ECHO OFF' & @LF $wString &= '' & @LF $wString &= 'SET /a COUNTER = 1' & @LF $wString &= ':STARTLOOP' & @LF $wString &= 'TASKLIST > "C:UsersADMINI~1AppDataLocalTempTEMPFILE.LOG"' & @LF $wString &= 'FIND /C "%1" "%TEMP%TEMPFILE.LOG"' & @LF $wString &= 'IF %ERRORLEVEL% NEQ 0 (' & @LF $wString &= 'GOTO EXITLOOP' & @LF $wString &= ')' & @LF $wString &= ') ELSE (' & @LF $wString &= 'ECHO WAITING...LOOP #%COUNTER%' & @LF $wString &= 'PING 127.0.0.1 -n 1 -w 500 >NUL' & @LF $wString &= 'SET /a COUNTER += 1' & @LF $wString &= 'GOTO STARTLOOP' & @LF $wString &= '' & @LF $wString &= ':EXITLOOP' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO %2 HAS EXITED...' & @LF $wString &= '@ECHO RENAMING %2 TO "%~nx3"' & @LF $wString &= 'PING 127.0.0.1 -n 1 -w 1000 >NUL' & @LF $wString &= 'REN %2 "%~nx3"' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO CHECK TO SEE IF FILE HAS BEEN RENAMED' & @LF $wString &= 'PAUSE' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO RENAMING %3 TO "%~nx2"' & @LF $wString &= 'PING 127.0.0.1 -n 1 -w 1000 >NUL' & @LF $wString &= 'REN %3 "%~nx2"' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO CHECK TO SEE IF FILE HAS BEEN RENAMED' & @LF $wString &= 'PAUSE' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO...' & @LF $wString &= '@ECHO EXITING BATCH SCRIPT' & @LF $wString &= 'DEL /Q "C:UsersADMINI~1AppDataLocalTempTEMPFILE.LOG"' & @LF $wString &= 'PAUSE' & @LF $wString &= 'DEL /Q %0' $hFile = FileOpen($sTempFile, 2) FileWrite($hFile, $wString) FileClose($hFile) ShellExecute($sTempFile, $iParameters) EndFunc ;==>_SelfRenameBatch Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now