Что нового

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

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Как восстановить удаленный в корзину файл ?
 

TheBloodTear

Знающий
Сообщения
36
Репутация
9
Код:
ShellExecute ("::{645FF040-5081-101B-9F08-00AA002F954E}")


Хммм.. Открывать то, открывается, а вот восстановить чтот хз как:smile:..
 

El Panda

Продвинутый
Сообщения
101
Репутация
59
Как вариант скопировать его обратно из папки RECYCLER нужного диска, вопрос только в том как определить конкретный файл.
Но вроде как там есть файл индексов...
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
El Panda сказал(а):
Как вариант скопировать его обратно из папки RECYCLER нужного диска, вопрос только в том как определить конкретный файл.
Но вроде как там есть файл индексов...
Похоже вопрос не так уж прост. Давно не могу найти решение.
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1 573
Репутация
334
Почему бы не просканировать все диски с папками RECYCLER на наличие данного файла?

P.S. Удалил файл, вручную проверил все диски, все файлы там одни и те же. Вот незадача только с выпуском системы. Если это XP, то создает папку
Код:
D:\RECYCLER\S-1-5-21-842925246-1844823847-682003330-1003
(например)
Если Win 7, то
Код:
C:\$Recycle.Bin\S-1-5-21-4132900103-3613051719-553855155-1001
(например)
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Medic84 [?]
Вот незадача только с выпуском системы. Если это XP, то создает папку
У меня Виста :
Код:
C:\$Recycle.Bin\S-1-5-21-740529958-3378912036-438458945-1000
C:\$Recycle.Bin\S-1-5-21-51003140-4199384537-3980697693-500
Да и на других дисках тоже папки , на некоторых по 2
Внутри имена некоторых файлов закодирована
 

Guezt

Продвинутый
Сообщения
335
Репутация
81
Medic84 [?]
Почему бы не просканировать все диски с папками RECYCLER на наличие данного файла?
Удаленные файлы имеют другое название, и пути восстановления с оригинальным названием файлов лежат в бинарном файле INFO2 ( это в ХР ) так, что не знаю, что это даст. ИМХО
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Первое, что приходит на ум, это работать непосредственно с окном корзины.

Код:
#Include <Array.au3>
#Include <GUIListView.au3>

$Name = RegRead('HKCR\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}', '')
ShellExecute('::{645FF040-5081-101B-9F08-00AA002F954E}', '', '', '', @SW_HIDE)
If Not WinWait($Name, '', 3) Then
	MsgBox(16, 'Error', 'Error!')
	Exit
EndIf
$hWnd = WinGetHandle($Name)
$hList = ControlGetHandle($Name, '', 'SysListView321')
$Count = _GUICtrlListView_GetItemCount($hList)
Dim $Data[$Count + 1][2]
$Data[0][0] = 'Name'
$Data[0][1] = 'Original Location'
For $i = 1 To $Count
	For $j = 0 To 1
		$Data[$i][$j] = _GUICtrlListView_GetItemText($hList, $i - 1, $j)
	Next
Next
WinClose($hWnd)

_ArrayDisplay($Data)
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Yashied [?]
Первое, что приходит на ум, это работать непосредственно с окном корзины.
Если нет других решений ,то можно
Но что дальше ? Неужели кликать по элементам окна ?

Кроме того нужно учесть возможность присутствия одноименных файлов
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
gregaz [?]
Но что дальше ? Неужели кликать по элементам окна ?
Можно так:

Код:
_GUICtrlListView_SetItemSelected($hList, $Index, 1, 1)
_SendMessage($hWnd, $WM_COMMAND, $ID_Restore, 0)


Т.е. выделяешь нужный файл ($Index), затем меню Restore ($ID_Restore). Значение $ID_Restore можно посмотреть в любом редакторе ресурсов (к сожалению нет под рукой) или в Google.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 243
Репутация
2 345
Откапал в гугле примерно вот что:

Код:
ConsoleWrite(_FileRecycleRestore(@DesktopDir, "~~Wiki.jpg"))

Func _FileRecycleRestore($sSourcePath, $sFileName)
    Local Const $RECYCLE_BIN = 10
    Local $objShell, $objFolder, $objFolderItem, $colItems
    
    $objShell = ObjCreate("Shell.Application")
    $objFolder = $objShell.Namespace($RECYCLE_BIN)
    $objFolderItem = $objFolder.Self
    $colItems = $objFolder.Items
	
    If IsObj($objShell) And Not @error Then
        For $objItem In $colItems
			$sName = $objFolder.GetDetailsOf($objItem, 0)
			$sSrcPath = $objFolder.GetDetailsOf($objItem, 1)
			
			If $sSrcPath = $sSourcePath And $sName = $sFileName Then
				$objFolderItem.InvokeVerbEx("Восстановить", $sSrcPath & "\" & $sName)
				Return FileCopy($objFolderItem.Path & "\" & $sName, $sSrcPath & "\" & $sName)
			EndIf
			
;~ 			$objFolder.GetDetailsOf($objItem, Number...)
;~          0 Name: dvdsig.md5
;~ 			1 Original Location: C:\VISTAG\D1
;~ 			2 Date Deleted: 3/20/2007 6:54 PM
;~ 			3 Size: 32 KB
;~ 			4 Type: MD5 File
;~ 			5 Date Modified: 3/20/2007 6:02 PM
;~ 			6 Date Created: 3/20/2007 5:59 PM
;~ 			7 Date Accessed: 3/20/2007 12:00 AM
;~ 			8 Attributes: A
;~ 			9 Status: Online
;~ 			10 Owner: Everyone
;~ 			11 Author:
;~ 			12 Title:
;~ 			13 Subject:
;~ 			14 Category:
;~ 			15 Pages:
;~ 			16 Comments:
;~ 			17 Copyright:
;~ 			18 Artist:
;~ 			19 Album Title:
;~ 			20 Year:
;~ 			21 Track Number:
;~ 			22 Genre:
;~ 			23 Duration:
;~ 			24 Bit Rate:
;~ 			25 Protected:
;~ 			26 Camera Model:
;~ 			27 Date Picture Taken:
;~ 			28 Dimensions:
;~ 			29 :
;~ 			30 :
;~ 			31 Episode Name:
;~ 			32 Program Description:
;~ 			33 :
		Next
    EndIf
	
    Return SetError(1, 0, -1)
EndFunc


но оно не работает, есть мысли на этот счёт? :whistle:
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Yashied [?]
Т.е. выделяешь нужный файл ($Index), затем меню Restore ($ID_Restore). Значение $ID_Restore можно посмотреть в любом редакторе ресурсов (к сожалению нет под рукой) или в Google.
А как определить нужный файл ( файл , который был только что удален) ?
Их там может быть несколько одного имени и удален был из одной папки.

Допустим даже я нашел и выполнил выделение второго (1) файла :
Код:
_GUICtrlListView_SetItemSelected($hList, 1, 1, 1)


Почему у меня не получается проверить выделение с помощью ?
Код:
GUICtrlListView_GetSelectedIndices($hList)


А послать сообщение :
Код:
$ID_Restore=101
_SendMessage($hWnd, $WM_COMMAND, $ID_Restore, 0)

вообще не удается ?

CreatoR [?]
но оно не работает, есть мысли на этот счёт?
У меня нет
 

Yashied

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

А как определить нужный файл ( файл , который был только что удален)?
Почему у меня не получается проверить выделение с помощью?
Код:
#Include <Array.au3>
#Include <GUIListView.au3>

$Name = RegRead('HKCR\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}', '')
ShellExecute('::{645FF040-5081-101B-9F08-00AA002F954E}', '', '', '', @SW_HIDE)
If Not WinWait($Name, '', 3) Then
    MsgBox(16, 'Error', 'Error!')
    Exit
EndIf
$hWnd = WinGetHandle($Name)
$hList = ControlGetHandle($Name, '', 'SysListView321')
$Count = _GUICtrlListView_GetItemCount($hList)
Dim $Data[$Count + 1][3]
$Data[0][0] = 'Name'
$Data[0][1] = 'Original Location'
$Data[0][2] = 'Date Deleted'
For $i = 1 To $Count
    For $j = 0 To 2
        $Data[$i][$j] = _GUICtrlListView_GetItemText($hList, $i - 1, $j)
    Next
Next
_GUICtrlListView_SetItemSelected($hList, 1, 1, 1)
ConsoleWrite(_GUICtrlListView_GetSelectedIndices($hList) & @CR)
WinClose($hWnd)

_ArrayDisplay($Data)


вообще не удается?
Значит ID не тот.
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
С
Код:
 _GUICtrlListView_SetItemSelected($hList, 1, 1, 1)
разобрался .
Я пытался читать уже после :
Код:
WinClose($hWnd)
b]Yashied[/b] [?]
Значит ID не тот.
Просьба помочь найти правильный $ID_Restore
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 243
Репутация
2 345
Yashied [?]
$Name = RegRead('HKCR\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}', '')
Это не везде будет работать, если пользователь сменил название у корзины, то заголовок будет другим. Есть ещё вот это:
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Несколько примитивно , но при отсутствии других решений , вроде работоспособно.
Учитывая то , на Висте удаляемый файл в корзине представляется в виде двух файлов :
Код:
$Iabcdef.ext   ; вспомогательныйфайл
$Rabcdef.ext  ; оригинальный файл
Перед удалением определяем дату создания файла
Выполняем сканирование и находим файл ($R.......) с этой датой создания .
Код:
#Include <Array.au3>
#include <File.au3>

Global $sRezultat
$hFile [email protected] & '\Test - Copy.txt' ; удаляемый файл
$iTime=FileGetTime ($hFile,0 ,1)
FileRecycle($hFile) 

$hDisc=StringLeft ( $hFile, 2 )
$sFolder=$hDisc & '\$Recycle.Bin'

$sFind=_FindFiles($sFolder, '*.*' )
$aFind=StringSplit (StringTrimRight ( $sFind, 1 ) , '|' )
;_ArrayDisplay($aFind)

For $i=1 To UBound($aFind)-1
   If Not StringInStr ( $aFind[$i],'$R') Then  ContinueLoop
   If FileGetTime ( $aFind[$i],0,1) = $iTime  Then ExitLoop
Next

$iProc=FileCopy($aFind[$i],$hFile)
If $iProc=1 Then MsgBox(0,'',"Файл восстановлен",1 )

Func _FindFiles($sRoot, $sFile)
   ; By Yashied
   Local $FileList
   $FileList = _FileListToArray($sRoot, $sFile, 1)
   If Not @error Then
	  For $i = 1 To $FileList[0]
		 $sRezultat &= $sRoot & '\' & $FileList[$i] & '|'
	  Next
   EndIf
   $FileList = _FileListToArray($sRoot, '*', 2)
   If Not @error Then
	  For $i = 1 To $FileList[0]
		 _FindFiles($sRoot & '\' & $FileList[$i], $sFile)
	  Next
   EndIf
   Return $sRezultat
 EndFunc   ;==>_FindFiles


Просьба потестировать
Как это будет на XP или 7 не знаю
P.S. Я специально выполняю копирование файла из корзины , а не перемещение т.к. не знаю повлияет ли перемещение на способность восстановления системы. ???


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

Или для последнего удаленного файла :

Учитывая то , что
Код:
$Iabcdef.ext   ; вспомогательныйфайл имеет дату появления в корзине
$Rabcdef.ext  ; оригинальный файл имеет оригинальную дату создания
Код:
#Include <Array.au3>
#include <File.au3>

Global $sRezultat,$iTime, $ii
$hFile [email protected] & '\Test - Copy.txt' ; удаляемый файл
FileRecycle($hFile) 
;MsgBox(0,'','')
$hDisc=StringLeft ( $hFile, 2 )
$sFolder=$hDisc & '\$Recycle.Bin'

$sFind=_FindFiles($sFolder, '*.*' )
$aFind=StringSplit (StringTrimRight ( $sFind, 1 ) , '|' )
;_ArrayDisplay($aFind)

For $i=1 To UBound($aFind)-1
   If Not StringInStr ( $aFind[$i],'$I') Then  ContinueLoop
   If FileGetTime ( $aFind[$i],0,1) > $iTime  Then $ii=$i
   $iTime=FileGetTime ( $aFind[$i],0 ,1)
Next

$sFile=StringReplace ( $aFind[$ii], "$I","$R")
$iProc=FileCopy($sFile,$hFile)
If $iProc=1 Then MsgBox(0,'',"Файл восстановлен",1 )

;..................Func _FindFiles ........

Здесь есть ограничение : не удалять одновременно несколько файлов
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 243
Репутация
2 345
gregaz [?]
Просьба потестировать
Как это будет на XP или 7 не знаю
На XP не работает, т.к нет папки $Recycle.Bin. А даже если указать правильный путь, файл оттуда не копируется.
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
CreatoR [?]
На XP не работает, т.к нет папки $Recycle.Bin. А даже если указать правильный путь, файл оттуда не копируется.
Странно. На Висте нормально копируется???
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Вот выяснил такой код. На XP вроде работает, просьба проверить на других OS.

Код:
$strSpecialFolderName = "Recycle Bin"
$objRecycleBin = GetSpecialFolderObject($strSpecialFolderName)
; 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(@CRLF)
Next
; Returns SpecialFolder based upon name of folder
Func GetSpecialFolderObject($NameOfFolder)
	Local $objShellApp = ObjCreate("Shell.Application")
	For $i = 0 To 40 ;40 is highest value for special folders
		$objSpecialFolder = $objShellApp.NameSpace($i)
		If $objSpecialFolder.Title = $NameOfFolder Then
			Return $objSpecialFolder
		EndIf
	Next
	Return
EndFunc   ;==>GetSpecialFolderObject
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 243
Репутация
2 345
Yashied [?]
На XP вроде работает
Неа...

Код:
The requested action with this object has failed.:
If $objSpecialFolder.Title = $NameOfFolder Then
If $objSpecialFolder.Title ^ ERROR
 
Верх