Что нового

[Файловая система] Восстановление удаленного файла

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
На чем проверял? Вот другой вариант, на XP тоже OK.

Код:
$objRecycleBin = _GetRecycleBin()
If IsObj($objRecycleBin) Then
	; Get Special Folder based upon input name
	$objFolderItems = $objRecycleBin.Items() ; Get items within Recycle Bin
	For $objItem In $objFolderItems ; Delete all items within Special Folder
		If ($objItem.Type = "File Folder") Then ; Check for file type
			ConsoleWrite("Directory:")
		Else
			ConsoleWrite("File:")
		EndIf
		ConsoleWrite("Name=" & $objItem.Name & @CRLF)
		ConsoleWrite("Size=" & $objItem.Size & @CRLF)
		ConsoleWrite("recyclename:" & $objItem.Path & @CRLF)
		ConsoleWrite("Infotip:" & $objRecycleBin.GetDetailsOf($objItem, -1) & @CRLF)
		ConsoleWrite("+origin: " & StringRegExpReplace($objRecycleBin.GetDetailsOf($objItem, -1), ".*?: (.*)(?s).*", "\1") & @CRLF)
		ConsoleWrite(@CRLF)
	Next
Else
	MsgBox(0, '', "Could not get Recycle Bin")
EndIf
Func _GetRecycleBin()
	Local $objShellApp = ObjCreate("Shell.Application")
	Local $ssfBITBUCKET = 10
	Return $objShellApp.NameSpace($ssfBITBUCKET)
EndFunc   ;==>_GetRecycleBin
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
Yashied
Последний код у меня на XP работает. :smile:
Предпоследний - как у CreatoR`а.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
madmasles сказал(а):
Последний код у меня на XP работает.

На XP у меня тоже, но вот интересно как оно на Vist'е и 7?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
Yashied
А можно как-то добавить проверку пустой корзины?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
madmasles сказал(а):
А можно как-то добавить проверку пустой корзины?

Можно, но сначала нужно разобраться с работоспособностью в разных системах.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Yashied [?]
На чем проверял?
В смысле? на XP :smile:

Вот другой вариант, на XP тоже OK
Это работает. Но я вот пытаюсь соорудить функцию для восстановления указанного файла, но натыкаюсь на проблему получения оригинального имени файла, т.к в корзине они часто изменяются (видимо при совпадений имени файла):

Код:
$sFileName = InputBox("Recycled File Name", "Please type recycled file/folder name or path", @DesktopDir & "\File.txt")
If Not @error Then _FileRecycleRestore($sFileName)

Func _FileRecycleRestore($sFile)
	Local $ssfBITBUCKET = 10
	Local $oShellApp = ObjCreate("Shell.Application")
	Local $oRecycleBin = $oShellApp.NameSpace($ssfBITBUCKET)
	
	If Not IsObj($oRecycleBin) Then
		Return SetError(1, 0, "Could not get Recycle Bin")
	EndIf
	
	; Get Special Folder based upon input name
	$oFolderItems = $oRecycleBin.Items() ; Get items within Recycle Bin
	
	For $oItem In $oFolderItems ; Delete all items within Special Folder
		$sOriginFileName = $oItem.Name
		$sOriginPath = $oRecycleBin.GetDetailsOf($oItem, 1) & "\" & $sOriginFileName
		
		If $sOriginPath = $sFile Or $sOriginFileName = $sFile Then
			If $oItem.Type = "File Folder" Then ; Check for file type
				DirMove($oItem.Path, $sOriginPath)
			Else
				FileMove($oItem.Path, $sOriginPath)
			EndIf
			
			ExitLoop
		EndIf
	Next
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
madmasles

Вот функция, с помощью которой можно получить количество объектов в корзине и общий их (объектов) размер в байтах для заданного диска или для всех дисков сразу. Эта функция будет присутствовать в следующей версии (2.2) библиотеки WinAPIEx.au3.

Код:
; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_ShellQueryRecycleBin
; Description....: Retrieves the size of the Recycle Bin and the number of items in it, for a specified drive. 
; Syntax.........: _WinAPI_ShellQueryRecycleBin( $sRoot )
; Parameters.....: $sRoot  - The string that contains the path of the root drive on which the Recycle Bin is located. This string
;                            can be formatted with the drive, folder, and subfolder names, for example "c:\windows\system\".
;                            If this parameter is empty string, information is retrieved for all Recycle Bins on all drives.
; Return values..: Success - The array that contains the following information.
;
;                            [0] - The total size of all the objects in the specified Recycle Bin, in bytes. 
;                            [1] - The total number of items in the specified Recycle Bin. 
;
;                  Failure - 0 and sets the @error flag to non-zero.
; Author.........: Yashied
; Modified.......:
; Remarks........: None
; Related........:
; Link...........: @@MsdnLink@@ SHQueryRecycleBin
; Example........: Yes
; ===============================================================================================================================

Func _WinAPI_ShellQueryRecycleBin($sRoot)

	Local $tSHQUERYRBINFO = DllStructCreate('align 1;dword;int64;int64')

	DllStructSetData($tSHQUERYRBINFO, 1, DllStructGetSize($tSHQUERYRBINFO))

	Local $Ret = DllCall('shell32.dll', 'int', 'SHQueryRecycleBinW', 'wstr', $sRoot, 'ptr', DllStructGetPtr($tSHQUERYRBINFO))

	If (@error) Or (Not ($Ret[0] = 0)) Then
		Return SetError(1, 0, 0)
	EndIf

	Local $Result[2]

	$Result[0] = DllStructGetData($tSHQUERYRBINFO, 2)
	$Result[1] = DllStructGetData($tSHQUERYRBINFO, 3)

	Return $Result
EndFunc   ;==>_WinAPI_ShellQueryRecycleBin
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
CreatoR [?]
Но я вот пытаюсь соорудить функцию для восстановления указанного файла, но натыкаюсь на проблему получения оригинального имени файла, т.к в корзине они часто изменяются (видимо при совпадений имени файла):

Попробовал на Висте :

Папку восстанавливает
Если задать имя удаленного файла с расширением - то его не восстанавливает
Если задать имя удаленного файла без расширения то он восстанавливается без расширения

Похоже здесь :
Код:
If $sOriginPath = $sFile Or $sOriginFileName = $sFile Then
            If $oItem.Type = "File Folder" Then ; Check for file type
               ConsoleWrite ($oItem.Path & @CRLF)
			   ConsoleWrite ($sOriginPath & @CRLF)
			    DirMove($oItem.Path, $sOriginPath)
            Else
               ConsoleWrite ($oItem.Path & @CRLF)
			   ConsoleWrite ($sOriginPath & @CRLF)
			   FileMove($oItem.Path, $sOriginPath)
            EndIf
            
            ExitLoop
        EndIf

ошибка связана с наличием или отсутствием расширения при проверке условий :




Добавлено:
Сообщение автоматически объединено:

В
Код:
$oItem.Path

и
Код:
$sOriginPath = $oRecycleBin.GetDetailsOf($oItem, 1) & "\" & $sOriginFileName


отсутствует расширение файла
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Код:
GetDetailsOf (0): ORIGINAL FILENAME
GetDetailsOf (1): ORIGINAL PATH
GetDetailsOf (2): DELETED DATE 
GetDetailsOf (3): FILESIZE 
GetDetailsOf (4): FILETYPE DESCRIPTION
GetDetailsOf (5): A DATE (Modified Or accessed?)
GetDetailsOf (6): CRETATED DATE 
GetDetailsOf (7): A DATE (Modified Or accessed?)
GetDetailsOf (8): FILEATTRIBUTES
GetDetailsOf (9): Online - What Does this sztand for? Original Path accessible?
GetDetailsOf (10): 1 - What does this stand for?
GetDetailsOf (11): THE OWNER OF THE ITEM
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Вот так ищет и восстанавливает :
Код:
Func _FileRecycleRestore($sFile)
     $sExt=StringRegExpReplace($sFile, '^.*\.', '') 
     ;......................................
     ;$sOriginPath = $oRecycleBin.GetDetailsOf($oItem, 1) & "\" & $sOriginFileName
      $sOriginPath = $oRecycleBin.GetDetailsOf($oItem, 1) & "\" & $sOriginFileName & '.' & $sExt
    ;................................................
:



Добавлено:
Сообщение автоматически объединено:

Применить :
Код:
GetDetailsOf (4): FILETYPE DESCRIPTION
мне не удается
Может из-за получаемой формы представления расширения : "AutoIt - Script "
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Расширение отсутствует потому, что в системе включена опция скрытия расширений для известных типов файлов. Чертова корзина... :Censored: Но у меня расширение показывает при любом раскладе в $objItem.Path, можно взять из этого. Правда не знаю как на Vista/7.


Добавлено:
Сообщение автоматически объединено:

Вообщем у меня получилось вот что. На XP работает на ура, просьба проверить на Vista/7.

Код:
#Include <Array.au3>

Func _EnumRecycleBinItems($sRoot = '')

	Local $oShellApp, $oRecycleBin, $oFolderItems, $oItem

	$oShellApp = ObjCreate('Shell.Application')
	$oRecycleBin = $oShellApp.NameSpace(10)
	If Not IsObj($oRecycleBin) Then
		Return SetError(1, 0, 0)
	EndIf

	Local $Ret, $Result[101][6] = [[0]]

	$sRoot = StringStripWS($sRoot, 3)
	If $sRoot > '' Then
		If StringInStr($sRoot, ':') Then
			$sRoot = StringRegExpReplace($sRoot, ':.*', '')
		Else
			$sRoot = ''
		EndIf
		If Not FileExists($sRoot & ':') Then
			Return SetError(1, 0, 0)
		EndIf
	EndIf
	$Ret = DllCall('shell32.dll', 'none', 'SHGetSettings', 'uint*', 0, 'dword', 2)
	If @error Then
		Return SetError(1, 0, 0)
	EndIf
	$oFolderItems = $oRecycleBin.Items()
	For $oItem In $oFolderItems
		If ($sRoot > '') And ($sRoot <> StringLeft($oItem.Path, 1)) Then
			ContinueLoop
		EndIf
		$Result[0][0] += 1
		If $Result[0][0] > UBound($Result) - 1 Then
			ReDim $Result[$Result[0][0] + 100][UBound($Result, 2)]
		EndIf
		$Result[$Result[0][0]][0] = $oRecycleBin.GetDetailsOf($oItem, 0) ; Original name
		$Result[$Result[0][0]][1] = $oRecycleBin.GetDetailsOf($oItem, 1) ; Original path
		$Result[$Result[0][0]][2] = $oRecycleBin.GetDetailsOf($oItem, 2) ; Deleted date
;		$Result[$Result[0][0]][3] = $oRecycleBin.GetDetailsOf($oItem, 3) ; Size
		$Result[$Result[0][0]][3] = $oItem.Size ; Size
		$Result[$Result[0][0]][4] = FileGetAttrib($oItem.Path) ; Attributes
		$Result[$Result[0][0]][5] = $oItem.Path ; Recycle name
		If (Not $Ret[1]) And (Not StringInStr($Result[$Result[0][0]][4], 'D')) Then
			If StringInStr($Result[$Result[0][0]][5], '.') Then
				$Result[$Result[0][0]][0] &= StringRegExpReplace($Result[$Result[0][0]][5], '^.*\.', '.')
			EndIf
		EndIf
	Next
	ReDim $Result[$Result[0][0] + 1][UBound($Result, 2)] 
	Return $Result
EndFunc   ;==>_EnumRecycleBinItems

$Data = _EnumRecycleBinItems()
_ArrayDisplay($Data)
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
SyDr сказал(а):

OffTopic:
:thumbs_up: :huggles: :sorcerer: :beer:



Добавлено:
Сообщение автоматически объединено:

Ну что, тема решена?


Добавлено:
Сообщение автоматически объединено:

Немного усовершенствовал функцию, см. предыдущий ответ.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
И еще раз изменил функцию. Предыдущий вариант не работал с файлами типа test.au3.txt, теперь все OK.
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Yashied [?]
На XP работает на ура, просьба проверить на Vista/7.
На Висте все нормально

[?]
Ну что, тема решена?
Да , огромное спасибо всем , принявшим участие .
Yashied , классная работа :beer:
P.S. Ну и задал я задачку.
Недаром до сих пор ее никто не решал. А ведь возможность " ОТКАТА " после удаления файла достаточно актуальна :IL_AutoIt_1:
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Пример одного из вариантов применения ф-ии : _EnumRecycleBinItems при восстановлении удаленного файла
Код:
#include <GUIConstants.au3>
#include <GuiListView.au3>
#include <File.au3>

$hGUI = GUICreate('Demo File Restore',1110,600)
GUISetBkColor(0xB1B1B1)

$hLabelRecyCler=GUICtrlCreateLabel('Папка  корзины',5,5,100,20)	
$sStyle=BitOR($LVS_REPORT,$LVS_ShowSELALWAYS) 
$sExStyle=BitOR($LVS_EX_GRIDLINES,$LVS_EX_FULLROWSELECT)
$hListViewRecycler = GUICtrlCreateListView("", 5, 30, 800,520,$sStyle,$sExStyle)
GUICtrlSetBkColor(-1,0xDBDB00)
_GUICtrlListView_InsertColumn ($hListViewRecycler, 0, 'Original name', 160) 
_GUICtrlListView_InsertColumn ($hListViewRecycler, 1, 'Original Patch', 300)
_GUICtrlListView_InsertColumn ($hListViewRecycler, 2, 'Deleted Data', 100) 
_GUICtrlListView_InsertColumn ($hListViewRecycler, 3, 'Size', 50)
_GUICtrlListView_InsertColumn ($hListViewRecycler, 4, 'Atributes', 40)
_GUICtrlListView_InsertColumn ($hListViewRecycler, 5, 'Recycle name', 300)

$hLabelTempFolder=GUICtrlCreateLabel('Папка : Temp Folder' ,810,5,300,20)	
$hListView = GUICtrlCreateListView("", 810, 30, 300,520,$sStyle,$sExStyle)
GUICtrlSetBkColor(-1,0xDBDBDB)
_GUICtrlListView_InsertColumn ($hListView, 0, 'FileName', 160) 
_GUICtrlListView_InsertColumn ($hListView, 1, 'FileFullName', 700)

$hBtRestore = GUICtrlCreateButton ("Restore",10,570,70,20)
$hBtClearRecycler = GUICtrlCreateButton ("Clear Recycler",90,570,110,20)
$hBtTestFileCreate=GUICtrlCreateButton ("TestFile Create",610,-1,100,'')
$hBtDelete = GUICtrlCreateButton ("Delete",850,-1,70,'')
$hBtBack = GUICtrlCreateButton ("Back",1030,-1,'','')

GUISetState()
; Создаем в рабочей папке скрипта  Папку : " Temp Folder "
DirCreate(@ScriptDir & '\Temp Folder')
Update_RecyclerFolderLV($hListViewRecycler)
Update_TempFolderLV($hListView)

While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
	  Case $GUI_EVENT_CLOSE
		 FileDelete(@ScriptDir & '\Temp Folder')
		 Exit	
	  Case $hBtClearRecycler
		 FileRecycleEmpty()
	  Case $hBtTestFileCreate
		 ; Создаем в  папке : "Temp Folder "  файлы\папки для тестирования
		 For $i=1 To 3
			DirCreate(@ScriptDir & '\Temp Folder\TestFolder ' & $i)
			_FileCreate(@ScriptDir & '\Temp Folder\TestFile ' & $i & '.txt')
		 Next
	  Case $hBtDelete
		 $hItem=_GUICtrlListView_GetSelectedIndices($hListView)
		 If $hItem='' Then ContinueLoop
		 $hFile=_GUICtrlListView_GetItemText( GUICtrlGetHandle($hListView),$hItem,1)
		 FileRecycle($hFile)
	  Case $hBtBack
		 FileRestore($hFile)
	  Case $hBtRestore
		 $hItemRec=_GUICtrlListView_GetSelectedIndices($hListViewRecycler)
		 If $hItemRec='' Then ContinueLoop
		 $hFileRec=_GUICtrlListView_GetItemText( GUICtrlGetHandle($hListViewRecycler),$hItemRec,5)
		 FileRestore($hFileRec,1)
	  Case else
		 ContinueLoop
   EndSwitch
   Update_RecyclerFolderLV($hListViewRecycler)
   Update_TempFolderLV($hListView)
WEnd

Func Update_RecyclerFolderLV($hLV)
   $aData=_EnumRecycleBinItems()
   _GUICtrlListView_DeleteAllItems(GUICtrlGetHandle($hLV))
   For $i=1 To UBound($aData,1)-1
	   _GUICtrlListView_AddItem($hLV, $aData[$i][0])
	  For $j=1 To UBound($aData,2)-1
		 _GUICtrlListView_AddSubItem($hLV, $i-1,$aData[$i][$j],$j)
	  Next
   Next
EndFunc

Func Update_TempFolderLV($hLV)
   $aArray=_FileListToArray( @ScriptDir & '\Temp Folder','*.*',0)
   _GUICtrlListView_DeleteAllItems(GUICtrlGetHandle($hLV))
   For $i=1 To UBound($aArray,1)-1
	  _GUICtrlListView_AddItem($hLV,$aArray[$i])
	  _GUICtrlListView_AddSubItem($hLV, $i-1,@ScriptDir & '\Temp Folder\' & $aArray[$i],1)
   Next
EndFunc

Func FileRestore($sFile,$iFlag=0)
   $aData=_EnumRecycleBinItems()
   For $i=1 To UBound ($aData,1)-1
	  $sOriginalFullName=$aData[$i][1] & '\' &  $aData[$i][0]
	  $sRecyclerFullName=$aData[$i][5]
	  $sAtributes=$aData[$i][4]
	  $sCompare = $sOriginalFullName
	  If $iFlag <> 0 Then $sCompare = $sRecyclerFullName
	  If $sCompare=$sFile Then
		 If $sAtributes='D' Then
			DirMove($sRecyclerFullName , $sOriginalFullName)
		 Else
			FileMove($sRecyclerFullName , $sOriginalFullName)
		 EndIf
		 ExitLoop
	  EndIf 
   Next
EndFunc

Func _EnumRecycleBinItems($sRoot = '')

    Local $oShellApp, $oRecycleBin, $oFolderItems, $oItem

    $oShellApp = ObjCreate('Shell.Application')
    $oRecycleBin = $oShellApp.NameSpace(10)
    If Not IsObj($oRecycleBin) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $Ret, $Result[101][6] = [[0]]

    $sRoot = StringStripWS($sRoot, 3)
    If $sRoot > '' Then
        If StringInStr($sRoot, ':') Then
            $sRoot = StringRegExpReplace($sRoot, ':.*', '')
        Else
            $sRoot = ''
        EndIf
        If Not FileExists($sRoot & ':') Then
            Return SetError(1, 0, 0)
        EndIf
    EndIf
    $Ret = DllCall('shell32.dll', 'none', 'SHGetSettings', 'uint*', 0, 'dword', 2)
    If @error Then
        Return SetError(1, 0, 0)
    EndIf
    $oFolderItems = $oRecycleBin.Items()
    For $oItem In $oFolderItems
        If ($sRoot > '') And ($sRoot <> StringLeft($oItem.Path, 1)) Then
            ContinueLoop
        EndIf
        $Result[0][0] += 1
        If $Result[0][0] > UBound($Result) - 1 Then
            ReDim $Result[$Result[0][0] + 100][UBound($Result, 2)]
        EndIf
        $Result[$Result[0][0]][0] = $oRecycleBin.GetDetailsOf($oItem, 0) ; Original name
        $Result[$Result[0][0]][1] = $oRecycleBin.GetDetailsOf($oItem, 1) ; Original path
        $Result[$Result[0][0]][2] = $oRecycleBin.GetDetailsOf($oItem, 2) ; Deleted date
;       $Result[$Result[0][0]][3] = $oRecycleBin.GetDetailsOf($oItem, 3) ; Size
        $Result[$Result[0][0]][3] = $oItem.Size ; Size
        $Result[$Result[0][0]][4] = FileGetAttrib($oItem.Path) ; Attributes
        $Result[$Result[0][0]][5] = $oItem.Path ; Recycle name
        If (Not $Ret[1]) And (Not StringInStr($Result[$Result[0][0]][4], 'D')) Then
            If StringInStr($Result[$Result[0][0]][5], '.') Then
                $Result[$Result[0][0]][0] &= StringRegExpReplace($Result[$Result[0][0]][5], '^.*\.', '.')
            EndIf
        EndIf
    Next
    ReDim $Result[$Result[0][0] + 1][UBound($Result, 2)] 
    Return $Result
EndFunc   ;==>_EnumRecycleBinItems
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
gregaz [?]
Пример одного из вариантов применения ф-ии : _EnumRecycleBinItems при восстановлении удаленного файла...

Ты не поверишь, но я тоже хотел написать аналогичный пример, но лень меня одолела...

:smile:
 
Верх