Chetwood Posted November 4, 2004 Share Posted November 4, 2004 Well, I've finally managed to get my new version of MultiShrink out which is a small tool to enable batch processing with DVD Shrink. I've added a delete option that deletes the source dir once the encoding is done on that particular DVD. Problem is that in some not reproducible cases one file (always the last vob of a certain DVD) is not deleted and thus the source dir not removed. I've got no idea what's causing this cause the delete function is the last one to be executed after having - closed all open DVDs in that particular instance of DVD Shrink - closed that instance itself so that there should be no files open from that source dir whatsoever. Any idea how can I track this down? MultiMakeMKV: batch processing for MakeMKV (Win)MultiShrink: batch processing for DVD ShrinkOffizieller Übersetzer von DVD Shrink deutsch Link to comment Share on other sites More sharing options...
ezzetabi Posted November 4, 2004 Share Posted November 4, 2004 Can you delete the file in Windows? Link to comment Share on other sites More sharing options...
Chetwood Posted November 4, 2004 Author Share Posted November 4, 2004 Can you delete the file in Windows?<{POST_SNAPBACK}>Well, I haven't stood by the moment the DVD was encoded so I did not try to delete it manually the moment this instance of DVD Shrink was closed. However, when I got back to my PC in the morning I could delete the whole dir without any problems.I'm afraid it's similar to the effect you sometimes experience when installing software. The program's just been installed but you cannot yet delete the 'setup.exe' cause windows still got it locked before cleaning it from memory or something. MultiMakeMKV: batch processing for MakeMKV (Win)MultiShrink: batch processing for DVD ShrinkOffizieller Übersetzer von DVD Shrink deutsch Link to comment Share on other sites More sharing options...
JSThePatriot Posted November 4, 2004 Share Posted November 4, 2004 That is a good possibility. I know this probably is not a good way to do it, but I would put in a few seconds of sleep before the delete process is called. See if that helps. I dont know of any other way to really debug it. You could also after it is deleted do a FileExists() and if it does Delete it again. That might work :-? JS AutoIt Links File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out. ComputerGetInfo UDF's Updated! 11-23-2006 External Links Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more) Link to comment Share on other sites More sharing options...
ezzetabi Posted November 4, 2004 Share Posted November 4, 2004 (edited) Try deleting your file(s)/folder(s) with this: Those are funcs that allow deleting a file boottime if they can't deleted outright. expandcollapse popup;This is a func that is inside Run!, why not use it? ; http://crimsonfan.altervista.org ;_DeleteFolder() _DeleteFiles() Exit Func _DeleteFiles() Local $sSelection, $aSelection, $c, $cDel = 0 $sSelection = FileOpenDialog('What file(s) do you want to delete?', @HomeDrive, 'All (*)', 5) Select Case $sSelection = 1 Return 0 Case StringInStr($sSelection, '|') $aSelection = StringSplit($sSelection, '|') If StringRight($aSelection[1], 1) <> '\' Then $aSelection[1] = $aSelection[1] & '\' For $c = 2 To $aSelection[0] $cDel = $cDel + _DeleteFile($aSelection[1] & $aSelection[$c]) Next Case Else;The user selected only a file. $cDel = _DeleteFile($sSelection) EndSelect Return $cDel EndFunc ;==>_DeleteFiles Func _DeleteFolder() Local $sSelection, $iDelDir, $aFiles, $c, $cDel = 0 $iDelDir = MsgBox(32 + 3, 'Question.', 'Do you want to delete also the folder itself?' & @LF & @LF & 'No, please just delete the files/folders inside it.' & @LF & 'Yes, erase also the folder after emptying it.') If $iDelDir = 2 Then Return 0 ;6 = Yes, 7 = No $sSelection = FileSelectFolder('What folder do you want to delete?', @HomeDrive, 4) If @error Then Return 0 If StringRight($sSelection, 1) <> '\' Then $sSelection = $sSelection & '\' $aFiles = _FileSearch($sSelection, 1) For $c = 1 To $aFiles[0] If Not StringInStr(FileGetAttrib($aFiles[$c]), 'd') Then $cDel = $cDel + _DeleteFile($aFiles[$c]) EndIf;If $cDel is still 0 then all files has been deleted already, ; so the empty folders can be already removed too. Next Select Case $iDelDir = 6 And $cDel <> 0 If Not ($iOS = 3) Then RegWrite('HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce', $sSelection, 'reg_sz', @ComSpec & ' /c rd /s/q "' & $sSelection & '"') Else RegWrite('HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce', $sSelection, 'reg_sz', @ComSpec & ' /c deltree /y "' & $sSelection & '"') EndIf Case $iDelDir = 6 And $cDel = 0;The folder is deleted outright. DirRemove($sSelection, 1) Case $iDelDir = 7 And $cDel = 0 DirRemove($sSelection, 1) DirCreate($sSelection) Case $iDelDir = 7 And $cDel <> 0 If Not ($iOS = 3) Then RegWrite('HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce', $sSelection & '1', 'reg_sz', @ComSpec & ' /c rd /s/q "' & $sSelection & '"') RegWrite('HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce', $sSelection & '2', 'reg_sz', @ComSpec & ' /c md "' & $sSelection & '"') Else RegWrite('HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce', $sSelection, 'reg_sz', @ComSpec & ' /c deltree /y "' & $sSelection & '."') EndIf EndSelect Return $cDel EndFunc ;==>_DeleteFolder Func _DeleteFile($sFile) ; Description: Try to delete a file, if it fails it deletes it reboot time. ; Syntax: _DeleteFile( $sFilename ) ; Parameter(s): $sFilename - The name of the file to delete. No wildcards. ; Return Value(s): -1 The file does not exist ; 0 The file has already been deleted ; 1 The file will be deleted boot time ; Author(s): Ezzetabi ezzetabi@katamail.com Local $sPending, $sFile, $iLFpos If StringInStr($sFile, "*") Or StringInStr($sFile, "?") Then Return -2 If Not StringInStr($sFile, "\") Then $sFile = @WorkingDir & "\" & $sFile;Adds the full path If Not FileExists($sFile) Then Return -1 If FileDelete($sFile) Then Return 0 ;If the code arrives here it means that the file is in-use and so ;it will be deleted at the reboot. If @OSTYPE = "WIN32_NT" and @OSVersion <> 'WIN_NT4' Then;The Kernel is W2000 $sPending = RegRead("HKLM\System\CurrentControlSet\Control\Session Manager", _ "PendingFileRenameOperations") If $sPending = "" Then RegWrite("HKLM\System\CurrentControlSet\Control\Session Manager", _ "PendingFileRenameOperations", "reg_multi_sz", _ "\??\" & $sFile & @LF) Else $iLFpos = StringInStr($sPending, @LF, 0, -1) Select Case $iLFpos = 0 Or StringMid($sPending, $iLFpos - 1, 1) = @LF;Existing operation is a deletion RegWrite("HKLM\System\CurrentControlSet\Control\Session Manager", _ "PendingFileRenameOperations", "reg_multi_sz", $sPending & @LF & @LF & "\??\" & _ $sFile & @LF) Case StringMid($sPending, $iLFpos - 1, 1) <> @LF;Existing operation is a rename RegWrite("HKLM\System\CurrentControlSet\Control\Session Manager", _ "PendingFileRenameOperations", "reg_multi_sz", $sPending & @LF & "\??\" & _ $sFile & @LF) EndSelect EndIf Else;The Kernel is Win9x/Nt $sFile = FileGetShortName($sFile) $sPending = FileRead(@WindowsDir & "\wininit.ini", FileGetSize(@WindowsDir & "\wininit.ini")) If @error Then;The file wininit.ini DOES NOT exist. FileWrite(@WindowsDir & "\wininit.ini", "[rename]" & @CRLF & _ "NUL=" & $sFile) Else ;The file wininit.ini EXISTS Local $iPos, $sOldFile $iPos = StringInStr($sPending, "[rename]") If $iPos = 0 Then;The [Rename] section is not there. FileWrite(@WindowsDir & "\wininit.ini", @CRLF & "[rename]" & @CRLF & _ "NUL=" & $sFile);... So it is just added at the end. Else;The section [rename] is there $iPos = $iPos + 9;(7 of the word [rename] and 2 of @crlf) $sOldFile = StringRight($sPending, StringLen($sPending) - $iPos) $sPending = StringTrimRight($sPending, StringLen($sPending) - $iPos) ;$sPending contain the whole wininit.ini, I removed the right part after [rename] ;after coping it in $sOldFile $sPending = $sPending & "NUL=" & $sFile & @CRLF & $sOldFile ;I add the line for deleting. And re-add the right part removed. FileDelete(@WindowsDir & "\wininit.ini") FileWrite(@WindowsDir & "\wininit.ini", $sPending) ;I recreate the file EndIf EndIf EndIf Return 1 EndFunc ;==>_DeleteFile Func _FileSearch($sIstr, $bSF) ; $bSF = 1 means looking in subfolders ; $sSF = 0 means looking only in the current folder. ; An array is returned with the full path of all files found. The pos [0] keeps the number of elements. Local $sIstr, $bSF, $sCriteria, $sBuffer, $iH, $iH2, $sCS, $sCF, $sCF2, $sCP, $sFP, $sOutPut = '', $aNull[1] $sCP = StringLeft($sIstr, StringInStr($sIstr, '\', 0, -1)) If $sCP = '' Then $sCP = @WorkingDir & '\' $sCriteria = StringTrimLeft($sIstr, StringInStr($sIstr, '\', 0, -1)) If $sCriteria = '' Then $sCriteria = '*.*' ;To begin we seek in the starting path. $sCS = FileFindFirstFile($sCP & $sCriteria) While $sCS <> - 1 $sCF = FileFindNextFile($sCS) If @error Then FileClose($sCS) ExitLoop EndIf If $sCF = '.' Or $sCF = '..' Then ContinueLoop $sOutPut = $sOutPut & $sCP & $sCF & @LF Wend ;And after, if needed, in the rest of the folders. If $bSF = 1 Then $sBuffer = @CR & $sCP & '*' & @LF;The buffer is set for keeping the given path plus a *. Do $sCS = StringTrimLeft(StringLeft($sBuffer, StringInStr($sBuffer, @LF, 0, 1) - 1), 1);current search. $sCP = StringLeft($sCS, StringInStr($sCS, '\', 0, -1));Current search path. $iH = FileFindFirstFile($sCS) While $iH <> - 1 $sCF = FileFindNextFile($iH) If @error Then FileClose($iH) ExitLoop EndIf If $sCF = '.' Or $sCF = '..' Then ContinueLoop If StringInStr(FileGetAttrib($sCP & $sCF), 'd') Then $sBuffer = @CR & $sCP & $sCF & '\*' & @LF & $sBuffer;Every folder found is added in the begin of buffer $sFP = $sCP & $sCF & '\'; for future searches $iH2 = FileFindFirstFile($sFP & $sCriteria); and checked with the criteria. While $iH2 <> - 1 $sCF2 = FileFindNextFile($iH2) If @error Then FileClose($iH2) ExitLoop EndIf If $sCF2 = '.' Or $sCF2 = '..' Then ContinueLoop $sOutPut = $sOutPut & $sFP & $sCF2 & @LF;Found items are put in the Output. Wend EndIf Wend $sBuffer = StringReplace($sBuffer, @CR & $sCS & @LF, '') Until $sBuffer = '' EndIf If $sOutPut = '' Then $aNull[0] = 0 Return $aNull Else Return StringSplit(StringTrimRight($sOutPut, 1), @LF) EndIf EndFunc ;==>_FileSearch Edited November 4, 2004 by ezzetabi Link to comment Share on other sites More sharing options...
ezzetabi Posted November 4, 2004 Share Posted November 4, 2004 Or just as JS said... $sFileName = '';Full path here If StringInStr(FileGetAttrib($sFileName), 'd') Then Do DirRemove($sFileName,1) Sleep(1);avoid overloading CPU Until Not FileExists($sFileName) Else Do FileDelete($sFileName) Sleep(1) Until Not FileExists($sFileName) EndIf Link to comment Share on other sites More sharing options...
JSThePatriot Posted November 4, 2004 Share Posted November 4, 2004 I think to sleep properly without over loading CPU shouldnt it be atleast between 10-100? I dont know much I am not trying to correct I just want to know for my knowledge. JS AutoIt Links File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out. ComputerGetInfo UDF's Updated! 11-23-2006 External Links Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more) Link to comment Share on other sites More sharing options...
ezzetabi Posted November 4, 2004 Share Posted November 4, 2004 (edited) Well, you know. Nowadays ours microprocessors may have 3 or 4 Ghertz of clock rate, it means that they can do 3 000 000 000 - 4 000 000 000 single clock operations per second. So just awaiting a 1/1000 of sec means allow them doing 3 000 000 - 4 000 000 operations becore taking some clocks again for tring to delete again. (It is not a CPU expensive procedure) Of course there are no problems using a larger number if you prefere. Edit: typo. Edited November 4, 2004 by ezzetabi Link to comment Share on other sites More sharing options...
Chetwood Posted December 23, 2004 Author Share Posted December 23, 2004 Well, finally some time to script again.Or just as JS said...$sFileName = '';Full path here If StringInStr(FileGetAttrib($sFileName), 'd') Then Do DirRemove($sFileName,1) Sleep(1);avoid overloading CPU Until Not FileExists($sFileName) Else Do FileDelete($sFileName) Sleep(1) Until Not FileExists($sFileName) EndIf<{POST_SNAPBACK}>Looks fine to me, however the expression Until Not FileExists does not seem to work for me. Is there any expression that checks for the NON existence of files at all?I've tried a different approach: I'm checking if there's any file in the dir left, if so, the script should wait for a second and then try again to delete the dir recursively. It looks like this but does not work since I do not get '-1' returned:If $sourcedel = 1 And $reauthor = 0 Then $delfiles=$deldir & "\*.*" $search=FileFindFirstFile($delfiles) Do DirRemove($deldir, 1) Sleep(1000) Until $search = -1 FileClose($search) EndIfAny suggestions? MultiMakeMKV: batch processing for MakeMKV (Win)MultiShrink: batch processing for DVD ShrinkOffizieller Übersetzer von DVD Shrink deutsch Link to comment Share on other sites More sharing options...
phillip123adams Posted December 23, 2004 Share Posted December 23, 2004 I've tried a different approach: I'm checking if there's any file in the dir left, if so, the script should wait for a second and then try again to delete the dir recursively. It looks like this but does not work since I do not get '-1' returned:If $sourcedel = 1 And $reauthor = 0 Then $delfiles=$deldir & "\*.*" $search=FileFindFirstFile($delfiles) Do DirRemove($deldir, 1) Sleep(1000) Until $search = -1 FileClose($search) EndIfAny suggestions?<{POST_SNAPBACK}>Are there really files left in the folder, or is it because of how FileFindFirstFile works. When *.* is used with FileFindFirstFile, it always sees the "." and the ".." folders. This little tid-bit is hidden in the help file comment for the FileFindFirstFile example. I believe it was yesterday that someone had a similar problem and someone suggested using the DirGetSize function which returns 0 when the folder is empty. Phillip Link to comment Share on other sites More sharing options...
Chetwood Posted December 24, 2004 Author Share Posted December 24, 2004 I believe it was yesterday that someone had a similar problem and someone suggested using the DirGetSize function which returns 0 when the folder is empty.<{POST_SNAPBACK}>I've tried DirGetSize like thisIf $sourcedel = 1 And $reauthor = 0 Then $empty=DirGetSize($deldir) Do DirRemove($deldir,1) Sleep(1000) Until $empty=0 EndIfBut it never works since the Until is never reached. What weirds me out is that I can use my Total Commander and delete the entire $deldir manually, so it's obviously not locked anymore. Still the Do-loop is never left except I change it to Until $empty=8372224which is exactly the size of the $deldir (my dummy DVD) to be deleted in bytes. I don't get it. Let me stress that again: the instance of DVD Shrink as well as the DVD openend from this instance are closed before the $deldir command is reached. I've got no idea why it's not working. MultiMakeMKV: batch processing for MakeMKV (Win)MultiShrink: batch processing for DVD ShrinkOffizieller Übersetzer von DVD Shrink deutsch Link to comment Share on other sites More sharing options...
Developers Jos Posted December 24, 2004 Developers Share Posted December 24, 2004 (edited) If $sourcedel = 1 And $reauthor = 0 Then $empty=DirGetSize($deldir) Do DirRemove($deldir,1) Sleep(1000) Until $empty=0 EndIf Don't understand the logic for the Do.. until... $Empty is never update inside this loop. Why not just remove those 2 lines ? Edited December 24, 2004 by JdeB SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
phillip123adams Posted December 24, 2004 Share Posted December 24, 2004 (edited) I've tried DirGetSize like thisIf $sourcedel = 1 And $reauthor = 0 Then $empty=DirGetSize($deldir) Do DirRemove($deldir,1) Sleep(1000) Until $empty=0 EndIfBut it never works since the Until is never reached. What weirds me out is that I can use my Total Commander and delete the entire $deldir manually, so it's obviously not locked anymore. Still the Do-loop is never left except I change it to Until $empty=8372224which is exactly the size of the $deldir (my dummy DVD) to be deleted in bytes. I don't get it. Let me stress that again: the instance of DVD Shrink as well as the DVD openend from this instance are closed before the $deldir command is reached. I've got no idea why it's not working.<{POST_SNAPBACK}>What JdeB said, but to have you Do Until work, restructure it as follows:If $sourcedel = 1 And $reauthor = 0 Then Do DirRemove($deldir,1) Sleep(1000) Until DirGetSize($deldir) = -1EndIfEDIT:Oops. Changed value to -1 on the Until line because DirGetSize returns -1 when after the directory is deleted. Otherwise the loop will not exit. Edited December 24, 2004 by phillip123adams Phillip Link to comment Share on other sites More sharing options...
Chetwood Posted December 26, 2004 Author Share Posted December 26, 2004 (edited) What JdeB said, but to have you Do Until work, restructure it as follows:Duh, seems I'm even less of a programmer than I thought. However, your version seems to work fine. I can't be 100% sure since the error wasn't reproduciable. I've ripped about 10 DVDs with this new method and all dirs were deleted just fine. Thanks. Edited December 26, 2004 by Chetwood MultiMakeMKV: batch processing for MakeMKV (Win)MultiShrink: batch processing for DVD ShrinkOffizieller Übersetzer von DVD Shrink deutsch Link to comment Share on other sites More sharing options...
phillip123adams Posted December 26, 2004 Share Posted December 26, 2004 Duh, seems I'm even less of a programmer than I thought. However, your version seems to work fine. I can't be 100% sure since the error wasn't reproduciable. I've ripped about 10 DVDs with this new method and all dirs were deleted just fine. Thanks.<{POST_SNAPBACK}>I've been trying to get DirRemove to fail, but it has always worked for me on the first pass. However, you could modify your loop, as shown below, and if a failure occurs it will record the information in a text file, break the loop after 10 iterations, and open the text file in NotePad. You can test the code if you prevent the directory from being deleted by opening one of its text files in NotePad before running the script.; <<<< For testing only >>>> $sFile = "c:\DirRemove-Did-Not-Remove-Itself.txt" $Cnt = 0 ; <<<< For testing only >>>> If $sourcedel = 1 And $reauthor = 0 Then Do DirRemove($deldir,1) Sleep(1000) ; <<<< For testing only >>>> $DirSize = DirGetSize($deldir) If $DirSize <> -1 Then $Cnt = $Cnt + 1 SplashTextOn("DirRemove not working", $Cnt & ". Folder " & $deldir & " is " & $DirSize & " bytes on pass " & $Cnt & " at " & @Hour & ":" & @Min & ":" & @Sec, 400, 30) $hFile = FileOpen($sFile, 1); <<< adjust filename FileWriteLine($hFile, "Folder " & $deldir & " is " & $DirSize & " bytes on pass " & $Cnt & " at " & @Hour & ":" & @Min & ":" & @Sec) FileClose($hFile) Sleep(1000) SplashOff() If $Cnt = 10 Then ExitLoop EndIf ; <<<< For testing only >>>> Until DirGetSize($deldir) = -1 EndIf ; <<<< For testing only >>>> If $Cnt > 0 Then Run("NotePad.exe " & $sFile) ; <<<< For testing only >>>> Phillip 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