Что нового

[Файловая система] Поиск файлов на всех дисках и замена его на другой

cobra2029

Новичок
Сообщения
54
Репутация
0
Здравствуйте, снова нужна помощь.
Собственно тема уже избитая как я понимаю, поиск выдал множество ответов.
На их основе был собран скрипт, но проблема заключается в следующем:
Файл на дисках он находит но по почему то не заменяет.

Сам скрипт:
Код:
#AutoIt3Wrapper_Res_requestedExecutionLevel=highestAvailable

FileInstall('MasterServers.vdf', @TempDir & '\MasterServers.vdf', 1)

$sFileReplase = @TempDir&"\MasterServers.vdf" ;файл на который будем менять все найденные
$iCount = 0 ;счетчик замены
$sFileName = StringRegExpReplace($sFileReplase, '^.*\\', '')
$aDrive = DriveGetDrive('FIXED') ; ДЛЯ ВСЕХ ДИСКОВ
For $i = 1 To $aDrive[0]
	$aSearch = _FileSearch($aDrive[$i], $sFileName, 1)
                        For $m = 1 To $aSearch[0]
				 FileCopy($sFileReplase, $aSearch[$m], 1)
				$iCount += 1
		         Next
Next


Func _FileSearch($s_Path_Search, $s_File_Mask = '*', $i_Flag = 0, $i_SubDir = 1)
    ;фильтры для поиска нужно указывать через ;
    ;$i_Flag = 0 - Файлы и папки (по умолчанию)
    ;$i_Flag = 1 - Только файлы
    ;$i_Flag = 2 - Только папки
    ;$i_SubDir = 1 - Искать во всех подкаталогах (по умолчанию). Возвращает полные пути.
    ;$i_SubDir = 0 - Искать только в самой папке. Возвращает только имена файлов(папок).
    Local $s_Out, $a_Out, $s_Read, $h_Dir, $s_Attrib, $s_Subdir, $a_Masks

    If StringRight($s_Path_Search, 1) == '\' Then ;нужно, если $s_Path_Search - диск (например C:\)
        $s_Path_Search = StringTrimRight($s_Path_Search, 1)
    EndIf
    If $i_SubDir Then
        $s_Subdir = ' /S /B'
    Else
        $s_Subdir = ' /B'
    EndIf
    Switch $i_Flag
        Case 1
            $s_Attrib = ' /A-D'
        Case 2
            $s_Attrib = ' /AD'
        Case Else
            $s_Attrib = ' /A'
    EndSwitch
    $s_Out = StringToBinary('0' & @CRLF, 2)
    $a_Masks = StringSplit($s_File_Mask, ';')
    For $i = 1 To $a_Masks[0]
        $h_Dir = Run(@ComSpec & ' /U /C DIR "' & $s_Path_Search & '\' & $a_Masks[$i] & '"' & $s_Subdir & $s_Attrib, @SystemDir, @SW_HIDE, 6)
        If Not $h_Dir Then Return SetError(1)
        While 1
            $s_Read = StdoutRead($h_Dir, False, True)
            If @error Then
                ExitLoop
            EndIf
            If $s_Read <> "" Then
                $s_Out &= $s_Read
            EndIf
            Sleep(10)
        WEnd
    Next
    $a_Out = StringRegExp(BinaryToString($s_Out, 2), '[^\r\n]+', 3)
    If @error Then Return SetError(1)
    $a_Out[0] = UBound($a_Out) - 1
    Return $a_Out
EndFunc   ;==>_FileSearch


Ссылки на первичные источники информации:

http://autoit-script.ru/index.php/topic,4818.0.html
http://autoit-script.ru/index.php/topic,8950.0.html
http://autoit-script.ru/index.php/topic,5028.0.html


Заранее спасибо за помощь!



P.S. системы на которых тестил: Windows 7 x64, Windows XP, Windows 7 x86
P.S.2. на Windows 7 x64 находит и заменяет только на диске С
P.S.3. на Windows XP может или найти и заменить или найти и не заменить
P.S.4. на Windows 7 x86 не находит
P.S.5. для Windows 7 x64 - компилировал 64-х битную версию, для остальных соответственно.
P.S.6. для Windows 7 x64 и Windows 7 x86 запуск скрипта с админ правами

Не могу никак понять почему в одних случаях он работает в других либо совсем не работает либо на половину.
 

AZJIO

Меценат
Меценат
Сообщения
2,761
Репутация
1,152
cobra2029
Добавь статистику. Возможно понадобится снимать атрибут R. Мне для удаления приходилось добавлять, а то не удалялось.
Код:
$sLog
For $i = 1 To $aDrive[0]
	$aSearch = _FileSearch($aDrive[$i], $sFileName, 1)
	For $m = 1 To $aSearch[0]
		If FileCopy($sFileReplase, $aSearch[$m], 1) Then
			$iCount += 1
		Else
			$sLog &= @CRLF & $aSearch[$m] &' | '&FileGetAttrib($aSearch[$m])
		EndIf
	Next
Next
If $sLog Then
	$sLog = 'Источник = ' & $sFileReplase &@CRLF&@CRLF& 'Назначение: ' &@CRLF& $sLog
	If MsgBox(4, 'Копировать список в буфер?', $sLog)=6 Then ClipPut($sLog)
EndIf
 
Автор
C

cobra2029

Новичок
Сообщения
54
Репутация
0
атрибут "А" у всех найденных файлов.
пути выдает правильные, я уже сомневался, что он вообще ищет.

ну и вот собственно, что выдает:
Код:
Источник = C:\Users\17D3~1\AppData\Local\Temp\MasterServers.vdf

Назначение: 

c:\Users\Денис\AppData\Local\Temp\MasterServers.vdf | 
d:\MasterServers.vdf | A
e:\MasterServers.vdf | A
e:\auto it\77777\111\MasterServers.vdf | A
e:\auto it\77777\22222\11111\MasterServers.vdf | A
e:\auto it\1_1\333333\1111\MasterServers.vdf | A


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

проблема решилась добавлением
Код:
FileSetAttrib($aSearch[$m], '-AR')
FileSetAttrib($aSearch[$m], 'R')

конечно, возможно есть другое, более красивое решение, но я его не нашел.
 

AZJIO

Меценат
Меценат
Сообщения
2,761
Репутация
1,152
cobra2029

Код:
$sLog
For $i = 1 To $aDrive[0]
	$aSearch = _FileSearch($aDrive[$i], $sFileName, 1)
	For $m = 1 To $aSearch[0]
		$TrAtr=0
		If StringInStr(FileGetAttrib($aSearch[$m]), "A") Then
			FileSetAttrib($aSearch[$m], '-A')
			$TrAtr=1 ; сняли атрибут и включили триггер, чтобы восстановить
		EndIf
		If FileCopy($sFileReplase, $aSearch[$m], 1) Then
			$iCount += 1
		Else
			$sLog &= @CRLF & $aSearch[$m] &' | '&FileGetAttrib($aSearch[$m])
		EndIf
		If $TrAtr=1 Then FileSetAttrib($aSearch[$m], 'A') ; восстанавливаем атрибут
	Next
Next
If $sLog Then
	$sLog = 'Источник = ' & $sFileReplase &@CRLF&@CRLF& 'Назначение: ' &@CRLF& $sLog
	If MsgBox(4, 'Копировать список в буфер?', $sLog)=6 Then ClipPut($sLog)
EndIf
 

vanekzver

Новичок
Сообщения
91
Репутация
2
Для замены на windows 7 нужны права администратора.

Для запуска в режиме администрации нужно дополнить в начала скрипта:

Код:
If Not IsAdmin() Then
    ShellExecute(@AutoItExe, $CMDLineRaw, @WorkingDir, "runas", @SW_SHOWNORMAL)
    Exit
 EndIf


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

Код:
#NoTrayIcon
If Not IsAdmin() Then
    ShellExecute(@AutoItExe, $CMDLineRaw, @WorkingDir, "runas", @SW_SHOWNORMAL)
    Exit
 EndIf
$drives = DriveGetDrive('FIXED')
For $i = 1 To $drives[0]
    $aOut = _FileSearch($drives[$i], "MasterServers.vdf", 1)
	FileSetAttrib("MasterServers.vdf", "+R")
    If $aOut[0] = 0 Then
    Else
For $a = 1 To $aOut[0]
    FileInstall('MasterServers2.vdf', $aOut[$a], 1)
Next
    EndIf
Next
Func _FileSearch($sPath, $sFileMask, $iFlag = 0)    ;Функция для поиска файла
    Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib
    Switch $iFlag
        Case 1
            $sAttrib = ' /A-D'
        Case 2
            $sAttrib = ' /AD'
        Case Else
            $sAttrib = ' /A'
    EndSwitch
    $sOut = StringToBinary('0' & @CRLF, 2)
    $aMasks = StringSplit($sFileMask, ';')
    For $i = 1 To $aMasks[0]
        $hDir = Run(@ComSpec & ' /U /C DIR "' & $sPath & '\' & $aMasks[$i] & '" /S /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
        While 1
            $sRead = StdoutRead($hDir, False, True)
            If @error Then
                ExitLoop
            EndIf
            If $sRead <> "" Then
                $sOut &= $sRead
            EndIf
        Wend
    Next
    $aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
    If @error Then
        Return SetError(1)
    EndIf
    $aOut[0] = UBound($aOut)-1
    Return $aOut
 EndFunc


Вот полностью рабочая функция
 

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
superman
откройте тему отдельно.в своей теме уже опишите что нужно искать и на что менять.
так как в каждом случае есть свои особенности
лучше тему открыть в http://autoit-script.ru/index.php/board,8.0.html
 

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
superman [?]
Только я непойму куда что нужно вставить чтоб он заработал. У меня он с 0 компилируется. и неработает
ты же сказал что нужен этот скрипт. зачем что то куда то вставлять? имена файлов разные? возможно поэтому ошибки или нулевой результат.
поэтому и сказал: открыть новую тему, дать точные данные что где искать и куда перемещать. и тогда будут рабочие решения. иначе никто не поможет
 

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
код должен быть обрамлен тегами AutoIT
 

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
superman
я про теги в сообщении
если тебе нужно найти файл и заменить его то вот мой вариант. ищет в папках всех дисков.
Код:
#Include <FileOperations.au3>
$drives = DriveGetDrive('FIXED')

For $i = 1 To $drives[0]
    $aOut = _FO_FileSearch ($drives[$i] & '\', "MasterServers.vdf",True,125,1,2)
	    If  @error Then
		Exit
    Else
For $a = 0 To UBound($aOut) - 1
	    FileSetAttrib($aOut[$a], "-RS")
    FileInstall('MasterServers.vdf',$aOut[$a], 1)
Next
    EndIf
Next

для того чтобы скомпилировать код нужно чтобы рядом со скриптом был файл MasterServers.vdf
нужна библиотека FileOperations.au3
есть в теме о русской справке
 

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
superman
я выложил рабочий код. проверил его и выложил.
у тебя совсем другие условия замены. заменить нужно не один файл? Зачем ты привел этот лог из программы замена?
давай свой код и что нужно менять. и повторюсь - нужно было сделать отдельную тему. не важно что она похожа.

и еще. некоторые файлы чтобы заменить нужно снять еще и атрибут "системный".
а некоторые из них система в любом случае не даст заменить. так что ..... ;)

изменил предыдущий код. пробуй
 

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
Код:
#include <FileOperations.au3>
$drives = DriveGetDrive('FIXED')

Local $array_s[3] = ['MasterServers.vdf', 'rev_MasterServers.vdf', 'MasterServers2.vdf']
For $i = 1 To $drives[0]
	$aOut = _FO_FileSearch($drives[$i] & '\', "MasterServers.vdf|rev_MasterServers.vdf|MasterServers2.vdf", True, 125, 1, 2)
	If @error Then
		Exit
	Else
		For $a = 0 To UBound($aOut) - 1
			If $aOut[$a] = @ScriptDir & '\' & StringRegExpReplace($aOut[$a], '.*\\', '') Then ContinueLoop
			For $r = 0 To 2
				If StringRegExpReplace($aOut[$a], '.*\\', '') = $array_s[$r] Then
					FileSetAttrib($aOut[$a], "-R")
					FileCopy(@ScriptDir & '\' & $array_s[$r], $aOut[$a], 1)
				EndIf
			Next
		Next
	EndIf
Next

видно что не через FileInstall. файлы замены должны быть в папке со скриптом. во время работы скрипт их найдет, но замены не будет. так как есть условие пропускать этот шаг. во всех других папках файлы со сходными именами будут заменены на те, что в папке со скриптом


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

изменил предыдущий код
 

superman

Новичок
Сообщения
4
Репутация
0
Всем привет! Помогите сделать так чтобы файлы на которые производится замена не в папке находились а засунуть их в exe при компиляции!!!! Выручайте
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
vanekzver
Для запуска в режиме администрации нужно дополнить в начала скрипта:
Код:
#RequireAdmin


superman
чтобы файлы на которые производится замена не в папке находились а засунуть их в exe при компиляции!
Есть такая функция
Код:
FileInstall

И прочитай это: Как заставить FileInstall работать с каталогами?.
 

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
superman
видишь ли, в коде использует переменная, а в Fileinstall нельзя использовать переменную для файла.
можно сделать по другому. в начале кода , прямо после #include сделать
Код:
FileInstall('MasterServers.vdf',@ScriptDir & '\MasterServers.vdf');и так все три файла
;
;
;тут наша функция(код)
;
;
_________________________________________
;потом удаляем файлы из папки
For $r = 0 To 2
FileDelete(@ScriptDir & '\' & $array_s[$r])
Next
 

superman

Новичок
Сообщения
4
Репутация
0
Вроде Почти все как надо. Осталось чтобы атрибуты ставил назад ну или рессурсы добавлялись - Только Чтение + Скрытый
Вообщем надо чтобы ресурсы были скрытые и только для чтения. После выполнения программы атрибуты с ресурсов снять и удалить...
 

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
superman
ну так после
Код:
FileCopy
возвращаешь атрибуты обратно. все это в главной функции
смотри справку по
Код:
FileSetAttrib
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,320
superman,
Еще одно нецензурное слово и Вы будете забанены, а пока Ваше сообщение удаляю.
 

superman

Новичок
Сообщения
4
Репутация
0
Можно готовый код? У меня не получается применить конкретно к этим файлам атрибуты
 

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
Код:
#include <FileOperations.au3>
OnAutoItExitRegister('_exit')
FileInstall('MasterServers.vdf', @TempDir & '\' & 'MasterServers.vdf',1)
FileInstall('MasterServers2.vdf', @TempDir & '\' & 'MasterServers2.vdf',1)
FileInstall('rev_MasterServers.vdf', @TempDir & '\' & 'rev_MasterServers.vdf',1)
Dim $array_s[3] = ['MasterServers.vdf', 'rev_MasterServers.vdf', 'MasterServers2.vdf']
$drives = DriveGetDrive('FIXED')
For $i = 1 To $drives[0]
    $aOut = _FO_FileSearch($drives[$i] & '\', "MasterServers.vdf|rev_MasterServers.vdf|MasterServers2.vdf", True, 125, 1, 2)
    If @error Then
        Exit
    Else
        For $a = 0 To UBound($aOut) - 1
            If $aOut[$a] = @TempDir & '\' & StringRegExpReplace($aOut[$a], '.*\\', '') Then ContinueLoop
            For $r = 0 To 2
                If StringRegExpReplace($aOut[$a], '.*\\', '') = $array_s[$r] Then
                    FileSetAttrib($aOut[$a], "-RH")
                    FileCopy(@TempDir & '\' & $array_s[$r], $aOut[$a], 1)
					FileSetAttrib($aOut[$a], "+RH")

                EndIf
            Next
        Next
    EndIf
Next
Func _exit()
For $r = 0 To 2
	FileDelete(@TempDir & '\' & $array_s[$r])
Next
EndFunc
 

superman

Новичок
Сообщения
4
Репутация
0
Остался последний момент. АвтоИТ Может сам запустится после скачивания??
 
Верх