Что нового

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

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,590
Репутация
341
Почему бы не просканировать все диски с папками 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
Репутация
82
Medic84 [?]
Почему бы не просканировать все диски с папками RECYCLER на наличие данного файла?
Удаленные файлы имеют другое название, и пути восстановления с оригинальным названием файлов лежат в бинарном файле INFO2 ( это в ХР ) так, что не знаю, что это даст. ИМХО
 

Yashied

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

Код:
#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,724
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,673
Репутация
2,486
Откапал в гугле примерно вот что:

Код:
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,724
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,673
Репутация
2,486
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 =@ScriptDir & '\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 =@ScriptDir & '\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,673
Репутация
2,486
gregaz [?]
Просьба потестировать
Как это будет на XP или 7 не знаю
На XP не работает, т.к нет папки $Recycle.Bin. А даже если указать правильный путь, файл оттуда не копируется.
 
Автор
G

gregaz

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Вот выяснил такой код. На 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,673
Репутация
2,486
Yashied [?]
На XP вроде работает
Неа...

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