Как приложение с графическим интерфейсом, WinMerge, вероятно, не имеет никаких сигналов, позволяющих PowerShell узнать, что слияние завершено. Это не API. Любой из подходов ожидания, описанных до сих пор, вероятно, потерпит неудачу, потому что он ожидает закрытия процесса, который, по вашему замыслу, никогда не произойдет.
2 вещи для размышления:
- Если у WinMerge есть файл журнала, вы можете отслеживать файл журнала на наличие какого-либо сообщения о завершении задания. Вы можете написать процедуру ожидания, ищущую эту строку/текст.
- Если есть функция журнала, возможно, используйте журнал для просмотра заданий постфактум. Это может свести на нет необходимость оставлять интерфейс открытым, что решило бы проблему ожидания.
Обновление по комментариям и изменениям:
Я ошибался, я использовал WinMerge раньше как часть Tortoise SVN. Хотя я предпочитаю Beyond Compare.
Я не думаю, что вам нужно проверять файлы после RoboCopy. Достаточно надежно, чтобы коррупция действительно была внешним риском. RoboCopy использует стандартные API-интерфейсы Windows для копирования файлов, и сомнительно, что такой же скептицизм будет сопровождать копирование на основе графического интерфейса. Понятно, что некоторый скептицизм может возникнуть из-за запутанного множества вариантов. Однако эта сложность вращается вокруг того, что копировать, протоколировать и т. д., как только RoboCopy решит скопировать файл, он должен сделать это надежно или с ошибкой. Сама копия должна рассматриваться как отдельная и независимо от любого беспокойства, которое может возникнуть из-за сложности инструмента. И создание соответствующей команды Robocopy обычно является предварительным этапом, включающим тестирование, за которым не часто следуют такие проверки.
Примечание. Вы также можете использовать RoboCopy во второй раз, чтобы либо обновить данные, либо использовать параметр /L
, чтобы увидеть, не было ли что-то пропущено или изменено.
Примечание. Когда выполняется копирование файла, RoboCopy устанавливает время изменения любого нового целевого файла на 01.01.1980 и изменяет его в соответствии с источником только после завершения копирования. Если файл отличается по размеру или времени изменения, они также не изменяются до завершения передачи. Вот как можно перезапустить RoboCopy и все равно найти/переписать неполные копии.
Существует по крайней мере одна гипотетическая ситуация, которая может вызвать коррупцию. Когда устройство, например ускоритель WAN, оказывается между источником и получателем. Гипотетически RoboCopy может думать, что все в порядке, основываясь на ошибочных или поврежденных ответах от этого устройства.
Итак, имеем дело с маловероятным риском повреждения файла. Ваша первоначальная идея использовать Get-FileHash
звучит уместно. Однако обратите внимание, что хеширование выполняется только для содержимого файла. Файлы с одинаковым содержимым, но разными метаданными, такими как имя и дата, вернут один и тот же хэш. Это сильно отличается от того, как RoboCopy воспринимает и реагирует на различия файлов, которые во многом зависят от имени, даты и размера.
Примечание. В зависимости от параметров RoboCopy может учитывать другие метаданные; атрибуты и ACL приходят на ум.
Без написания огромного скрипта для вычисления и сравнения хэшей в большом наборе файлов вы можете просто запустить что-то вроде ниже для источника и назначения:
Get-ChildItem <Path> -Recurse |
Get-FileHash |
Select Path,Hash |
Out-File <SomeOutputPath>
Сделайте это в каждой из папок. Затем сравните полученные текстовые файлы в WinMerge, Beyond Compare и т. д.
Примечание. Возможно, вы захотите установить для параметра -Width
параметра Out-File
очень большое значение. Это может вместить очень длинные пути.
Примечание. Для Get-ChildItem
вы можете указать путь как \\?\c:\FolderName
, это позволит проходить очень длинные пути, хотя я не уверен, как отреагирует Get-FileHash
.
Примечание. Это может занять некоторое время и может привести к созданию огромных текстовых файлов.
Это, вероятно, не должно быть повторяемым процессом. После того, как вы убедились, что RoboCopy копирует с полной точностью, продолжать или пытаться что-то уточнить, вероятно, будет излишним.
Обновление:
Если вы хотите использовать RoboCopy для создания списка, подходящего для сравнения, вам нужно сделать несколько вещей:
- Вам нужно будет создать свою команду RoboCopy, чтобы максимально приблизиться к чистой линии/строке пути.
- Вам придется направить этот вывод в цикл
ForEach-Object{}
, чтобы манипулировать выходными строками; удаление непохожих ведущих частей пути.
Пример:
RoboCopy C:\temp\TestFiles3 "C:\Empty" /E /FP /NS /NC /NP /NJH /NJS /L |
ForEach-Object{ $_.Trim() -Replace "C:\\Temp\\" }
Эта команда RoboCopy:
- /E :: копировать подкаталоги, в том числе пустые.
- /FP :: включить в вывод полные пути к файлам.
- /NS::No Size — не регистрировать размеры файлов.
- /NC :: No Class - не регистрировать классы файлов.
- /NP :: No Progress — не отображать процент копирования.
- /NJH :: Нет заголовка задания.
- /NJS :: Нет резюме работы.
- /L :: Только список — не копировать, не ставить временные метки и не удалять какие-либо файлы.
Примечание. Эти описания взяты непосредственно из файла справки RoboCopy /?
. Это стоит прочитать!
Эти параметры будут выводить что-то вроде:
C:\temp\TestFiles3\
C:\temp\TestFiles3\TestFiles2\
C:\temp\TestFiles3\TestFiles2\Test1000_KB.txt
C:\temp\TestFiles3\TestFiles2\Test100_KB.txt
...
Затем цикл ForEach-Object{}
изменит данные на:
TestFiles3\
TestFiles3\TestFiles2\
TestFiles3\TestFiles2\Test1000_KB.txt
TestFiles3\TestFiles2\Test100_KB.txt
Вы можете видеть, что он обрезает пустое пространство и удаляет начальную часть пути в соответствии с инструкциями. Как упоминалось ранее, если вы добавите Out-File
и запустите как источник, так и место назначения, вы должны получить файлы, достойные сравнения...
Примечание. В примере используется -Replace
, поскольку .Replace()
чувствителен к регистру. Сообщество pwsh обычно предпочитает использовать нативный подход PowerShell...
person
Steven
schedule
26.09.2020