200,05
рейтинг
28 декабря 2015 в 13:38

Разработка → Как я искал (и нашел) разницу в двух побайтово идентичных файлах

Есть у нас одно .NET-приложение, которое умеет загружать и использовать плагины. Плагины — дело хорошее. Можно функционал расширять, можно оперативненько обновлять их со своего сайта, можно даже юзерам дать SDK и позволить писать свои плагины. Мы всё это и делали. Наши плагины представляли собой обычные .NET-сборки, которые нужно было подкинуть в определённую папку, откуда основное приложения их загружало и использовало. Ну, вы, наверное представляете как — Assembly.Load(), дальше ищем класс, реализующий необходимый интерфейс, создаём объект этого класса и т.д. Всё это работало давно, стабильно и ничто не предвещало беды. Но вдруг в какой-то момент появилась необходимость создать плагин, состоящий из нескольких файлов. В связи с этим было решено считать плагином не просто .NET-сборку (1 файл), а zip-архив, в котором может быть как одна сборка, так и несколько файлов. В связи с этим пришлось научить билд-сервер паковать плагины в архивы, а основное приложение — разархивировать их в нужное место. В общем-то задача на 10 строк кода. Ничто не предвещало беды. И вот скачиваю я с билд-сервера собранный архив с плагином, разархивирую его в нужную папку, запускаю приложение, и… не работает! Стоп, как не работает? Это ведь тот же плагин!

Дальше — больше. Прошу проделать ту же самую процедуру моего коллегу, на его компьютере. Он пробует — и у него всё работает! Но как же так? Одна версия приложения, один и тот же файл с билд-сервера. Какая-то разница в окружении? Сажусь за компьютер коллеги, пробую ещё раз — не работает! Он в этом время пробует на моём — работает! То есть получается, что файл «помнит», кто его разархивировал! Зовём третьего коллегу понаблюдать этот цирк. Последовательно, на одном и том же компьютере, по очереди делаем одни и те же действия: скачиваем архив с плагином, разархивируем в нужную папку, запускаем приложение. Когда это делаю я — программа не видит плагин, когда это делает коллега — всё работает. На третьем круге этих интересных экспериментов вдруг замечаем разницу в действиях: я разархивировал плагин стандартными средствами Windows, а мой коллега — с помощью 7-Zip. И то и другое вызывалось нами из контекстного меню архива, так что разницу в клик по не тому пункту вначале никто не замечал. Ну ок. Получается, файл, извлечённый из zip-архива с помощью 7-zip, отличается от того же файла из того же архива, извлечённого с помощью стандартного архиватора Windows?

Кстати, пока вы не открыли статью под катом, ответьте-ка сами для себя на вопрос, может ли такое быть, что содержимое файлов валидного zip-архива при разархивации 7-zip и через проводник Windows будет разным?

Ну, не будем гадать и сравним файлы с помощью WinMerge:



Получается, файлы одинаковые и должны одинаково загружаться и обрабатываться? Как бы не так! WinMerge врёт. Файлы разные. И загружаются они .NETом тоже по-разному.

А теперь будет страшная правда

При загрузке файла из интернета Windows ставит на него специальный «флаг», означающий зону доверия, соответствующую сайту, с которого он был загружен. Я думаю, многие видели при попытке запуска только что скачанного исполняемого файла предупреждения о том, что запускать его, возможно, не стоит, надо подумать, вот посмотрите сертификат и скажите, что делать. В зависимости от политик безопасности и происхождения файла уровень параноидальности этих предупреждений может быть разным — от полного их отсутствия (работаем под админом, UAC отключен, файл подписан) до блокировки запуска (корпоративное окружение, неподписанный файл). Есть и несколько промежуточных стадий, где надо один или несколько раз сказать «да, запускаем». Но это всё ведь работает только для exe-файлов, да? Нет! На скачанный из интернета dll-файл или архив тоже будет повешен данный флаг! С технической точки зрения он является альтернативным файловым потоком NTFS, который можно посмотреть, например, через утилиту AlternateStreamView ну или через команду:

more < Plugin.dll:Zone.Identifier

И вот здесь мы имеем стечение следующих обстоятельств:

  1. Браузер при загрузке создаёт для скачанного архива альтернативный файловый поток «Zone.Identifier» и пишет туда ID зоны, откуда пришел файл.
  2. Стандартный архиватор проводника Windows при разархивировании читает не только основной файловый поток, но и альтернативные, и добавляет их к каждому извлечённому файлу. (7-Zip этого не делает).
  3. Утилита WinMerge сравнивает только основные файловые потоки и говорит, что файлы, созданные 7-Zip и проводником идентичны.
  4. В .NET метод Assembly.Load() тоже читает альтернативные файловые потоки, находит идентификатор зоны с пониженным доверием — и отказывается загружать файл! При этом привычные пользователю сообщения с просьбой подтвердить запуск недоверенного приложения не показываются и мы получаем наш баг.

Бороться с проблемой достаточно просто — нужно проверять\удалять данный файловый поток. В Windows для этого можно вызвать свойства файла и нажать там кнопку Unblock (ну или делать это програмно).



Если вы сделаете это для архива до извлечения из него файлов — идентификатор зоны пропадёт и для всех извлеченных в последствии файлов.

Возможно, я тут рассказал банальные и всем известные вещи, однако тот факт, что из одного и того же архива различные архиваторы могут извлечь разные файлы, да ещё и так хитро разные, что WinMerge этой разницы не видит, а .NET — видит, лично для меня было интересным открытием.
Автор: @tangro

Комментарии (88)

  • +12
    Познавательно. Спасибо!
  • +21
    После прочтения заголовка, сразу подумалось что скорее всего дело в файловых потоках.
    А про конкретно Zone.Identifier не знал.
    • +1
      Аналогично. Про файловые потоки сразу вспомнилось, а вот как они могут оказаться в .ZIP файле — я до открытия спойлера придумать не смог.
  • +1
    А такое поведение Assembly.Load (отсутствие окошка с запросом) — это баг? И как вы решили проблему для конечных пользователей — написали инструкцию по снятию флажка?
    • +1
      Конечным пользователям это не нужно, поскольку свои плагины программа скачивает сама и имеет полный контроль над тем, как и качать и как открывать. На них этот флаг, собственно, даже и не появлялся, поскольку файлы качались своим даунлоадером. Для загрузки плагинов сторонних производителей добавим проверку этого флага и запросим подтверждение его снятия.
      • 0
        Ясно, спасибо.
    • +13
      Такое поведение Assembly.Load — задокументированная норма. Этот метод при попытке открыть «заблокированный» файл бросает System.IO.FileLoadException с текстом «Operation is not supported. (Exception from HRESULT: 0x80131515)», на которые гугл даёт совершенно однозначные ответы.
      А «окошко с запросом» это уже совсем не удел библиотеки. Этим пусть UI занимается, в котором (на примере статьи) на него просто забили, молча подавив exception (видимо — раз просто "не работает" у автора, а не "ошибка").
      • +2
        Всё так и есть, залогировали ошибку загрузки плагина и на этом всё. Собственно говоря, анализ логов и привёл к выявлению бага. Я эту часть опустил, она логически должна была бы быть между скриншотом WinMerge и разделом «страшная правда».
        • +3
          Логически она должна быть до всяких WinMerge и вместо капитанского поста. Подолбиться в приложение несколько раз под разными пользователями, посравнивать файлики winmerge и только потом догадаться посмотреть в свой же лог — это несколько странный подход к разработке.
          Я всё к тому, что сам пост высосан из пальца и можно свести к строчке "7zip игнорирует Zone.Identifier". Потому как Exception, бросаемый из Load() достаточен для идентификации проблемы и понимания способов её решения.
          • 0
            Всё так и есть. Только не «7zip игнорирует Zone.Identifier», а все архиваторы, кроме проводника Windows, его игнорируют.
            • 0
              Что это меняет?
              • +1
                Восприятие того факта, что это не 7zip ведёт себя как-то особенно, а архиватор Windows.
            • 0
              После слова «скачиваю», сразу понял о чем будет пост.
              Нарвался на такое давным давно, сделал в памяти зарубку, и как-то в голову не пришло трубить об этом всем свету.
              Хотя, да, для некоторых может быть откровением.
              И еще, врёте всё на счет «все архиваторы, кроме проводника Windows»!
              WinRar, например, не игнорирует Zone.Identifier.
              • 0
                Я вот даже не поленился поставить WinRar, чтобы проверить. И WinRar игнорирует Zone.Identifier.
                • 0
                  Перепроверил на всякий случай.
                  Windows 7 x64 (политики безопасности в основном без изменении),
                  WinRar 5.21 x64 (уже обновил до 5.30, что не повлияло на конечный результат),
                  7-Zip 15.12 x64.
                  Архив скачанный с инета -> имеется флаг.
                  Распаковываем через контекстное меню.
                  WinRar — флаг есть у всех извлеченных файлов.
                  7-Zip — все файлы не содержат флага.
    • +1
      А в .NET есть метод для снятия этой порчи «на лету»?

      P.S.
      Разработчик, конечно, оригинален, что ищет решения нетрадиционными путями.
      • +1
        var fileInfo = new FileInfo(path);
        fileInfo.DeleteAlternateDataStream(«Zone.Identifier»);
  • +2
    Я сразу подумал на NTFS-streams. Интересно, можно ли их редактировать программно — ну например этот же конкретный флаг? Если да, то как?
    • +2
    • +2
      Можно. Причём хоть notepad'ом. А в Windows XP можно было даже .exe файлы туда засовывать и запустить. Скажем выполняемый файл в потоке «readme.txt:game.exe» :-)

      В Windows Vista такое уж прямое безобразие запретили…
      • +1
        Странно, у меня другие данные.
        Сейчас проверил на Windows 10, права пользователя. Все отлично записывается и запускается.

        image
        • 0
          У меня сейчас и винты-то нет, чтобы проверить. Может файл, куда я пытался засунуть exe'щник уже содержал Zone.Identifier и потому не работал?
        • 0
          Form1? Уж не в Delphi ли написана прожка?!
          • +1
            Иконка не сходится. Это VS.
    • 0
      PowerShell
      #read all streams
      Get-item -Path D:\123.txt -Stream *
      
      #Add stream
      Add-Content -Path D:\123.txt -Value 'data' -Stream 'MyADS'
      
      #Read from stream
      Get-Content -Path D:\123.txt -Stream MyADS
      
  • –2
    ещё, dot.net неадекватно себя ведёт с сетевыми дисками, такая же проблема с зонами доступа.
    • +5
      неадекватно? т.е. настройки безопасности — это неадекват по-вашему?
      • +5
        неадекватно для пользователя, запускаю программу с сетевого диска- не работает, переношу — работает.
        • 0
          Блин, а я не мог понять, почему у меня в виртуалке не запускается твикер для Diablo 2, который на доте… Спасибо!
        • 0
          А разве пользователь не сам (ну или ИТ-служба его фирмы) выбрал такие настройки безопасности?
          • 0
            хорошо, ИТ служба установила настройки безопасности.
            Дело не в настройках, а их неочевидности, как и в посте выше о них узнать можно только экспериментальным путём.
            Не дотнет софт работает отлично.
  • +12
    Тоже сталкивался с такой проблемой.
    В итоге родился батник для разблокирования всех файлов в папке:

    FOR /R %%F IN (*.*) DO echo.>"%%F":Zone.Identifier
    
  • +1
    Ха, сколько раз мы накалывались с этим, сколько крови попортили и себе, и заказчикам:) Прям то ли ностальгия, то ли дежавю. Удивительно, что впервые вижу публикацию на эту тему.
  • –7
    Выходит, ваше основное приложение не имеет системы контроля целостности плагинов по контрольным суммам?
    • +3
      Разве контрольная сумма распространяется на альтернативные потоки? Вроде же только на тело файла.
    • +3
      Во-первых, контрольные суммы есть, но они для валидации корректности загрузки, ну и, как сказали выше, «обычная» контрольная сумма действительно считается лишь по телу файла — так что не поможет. Во-вторых, как же я могу знать контрольные суммы чужих плагинов, которые могут появиться откуда-угодно? В третьих, если придумывать механизм контрольных сумм с учетом альтернативных потоков, то сразу получается какое-то переусложнённое решение, поскольку альтернативный файловый поток может быть, может не быть, их может быть несколько, записано туда может быть много разных валидных или не валидных данных и т.д. Проще их убирать, чем возиться с анализом.
      • –5
        Формат контрольной суммы может быть оговорен в правилах оформления плагина — для чужих плагинов. Вещь необязательная, конечно, но может облегчить поиск проблем.
        Но вы, конечно, правы — проще убирать лишние метаданные, чем возиться с анализом.
  • +1
    Интересно, не сталкивался с таким.
    Но получается что разницы в двух побайтово идентичных файлах не нашли (поток файл не меняет).
    • 0
      Ну тут ведь дело в том, что считать «файлом». Есть мнение, что все файловые потоки равнозначны, а значит разное содержимое альтернативных потоков меняет файл.
      • +1
        Имхо. Поток это одежда на человеке, меняй, дополняй, человек от этого не изменится (иначе ломались бы все ЭЦП). А вот отношение к нему и работа с ним может.
      • +2
        Imho, NTFS streams это всё же метаданные, т.е не являются данными как таковыми, это доп. информация. В мире *nix это по сути Extended attributes (кстати, заметьте, как важно иногда адекватно назвать фичу). С этой точки зрения всё правильно — данные файлов побайтово равны и КС сойдутся, но метаданные различные и могут быть утеряны в некоторых случаях (равно как не все утилиты *nix дистрибутивов сохраняют EA при работе). И ровно также «Security» Extended attributes могут кардинально влиять на возможность работы с файлом, и также иногда вызывать недоумение. Тот же SELinux.
        • 0
          А если у вас на вашей NTFS лежит файлик из MacOS (не из MacOS X!) где полпрограммы может быть в потоке ресурсов — это всё ещё метаданные или уже нет?

          Потоки в NTFS, собственно, ради MacOS изначально появились :-)
          • 0
            Повторюсь, по моему мнению, потоки — это метаданные. Как их можно использовать — другой вопрос. Например, замечательна история, когда в потоки файлов windows, которую ставили в банкоматы, запихали трояна. Которого никто не заметил.

            А про «ради MacOS» — сможете пруф дать?
            • 0
              По сути мы приходим к обсуждению разницы между данным и метаданными. Это давний холивар, о нём даже в Википедии написано
              • 0
                Извините, в данном случае я не соглашусь. Всё абсолютно однозначно: содержимое файла — это последовательность произвольных байт/бит (не обязательно непрерывная, конечно), адресуемая тем или иным способом (имя, inode, смещение, и др). Это данные. Файловая система МОЖЕТ обеспечивать привязку дополнительных атрибутов. Вот дополнительные потоки NTFS — как раз один из вариантов этих атрибутов. Это метаданные.
                Поэтому, на мой взгляд, никакого холивара и всё вполне чётко разделено.
                • +4
                  Дополнительные аттрибуты являются такой же последовательностью байт/бит, тем же способом адресуемая, теми же функциями читаемая. А если содержимое альтертанивных потоков ещё и непосредственно влияет на поведение программы — какие-же это метаданные? Холивар из википедии во весь рост :)
                  • 0
                    Атрибуты хранятся в структуре ФС, для большинства *nix систем — внутри структуры inode. Это метаданные. Непосредственно данные храняться отдельно и читаются другими функциями.

                    >А если содержимое альтертанивных потоков ещё и непосредственно влияет на поведение программы — какие-же это метаданные
                    Хм. Самые натуральные =) Это метаданные, отвечающие за контекст работы с данными, но это НЕ сами данные.
                    • +1
                      Атрибуты хранятся в структуре ФС, для большинства *nix систем — внутри структуры inode. Это метаданные.
                      Час от часу не легче. То есть у нас теперь содержимое файла в 10 байт — это данные на ext2, и метаданные на NTFS или reiserfs?

                      Непосредственно данные храняться отельно и читаются другими функциями.
                      А могут и теми же самыми читаться.
                  • 0
                    А если содержимое альтертанивных потоков ещё и непосредственно влияет на поведение программы — какие-же это метаданные?
                    Ну тут сложный вопрос. «Расширенные атрибуты» в Linux'е тоже могут ой как влиять на поведение программы. Да и «нерасширенные» тоже. Аттрибуты «executable» есть и в Linux и в Windows!

                    Но тут всё-таки есть некая разница: SELinux всё-таки непосредственно на поведение программы не влияет, соответствующие аттрибуты учитываются ядром для того, чтобы давать (или не давать) доступ к другим, «настоящим», объектам. Если эти метаданные заменить, скажем, на «доступ ко всем объектам открыт для всех», то программа, скорее всего, заработает…

                    Но потоки-то в NTFS предназначались совсем для другого! При использовании с MacOS там хранится информация, которой больше нигде нет и которую не так-то просто восстановить при потере… Тут как-то уже совсем не кажется, что это можно назвать «метаданными».
                • 0
                  Вот дополнительные потоки NTFS — как раз один из вариантов этих атрибутов.
                  Ещё раз: изначальное предназначение потоков NTFS — хранение ресурсов. Иконок, менюшек, диалоговых окон.

                  Цитата из Википедии: редактор, к примеру, может хранить текст в «потоке данных», в то же время храня картинки, вставленные в тот же файл, в «потоке ресурсов». Вы хотите сказать, что картинка, вставленная в документ — это метаданные???
                  • 0
                    > Вы хотите сказать, что картинка, вставленная в документ — это метаданные???
                    Вы начинаете подменять понятия. Во-первых, что такое документ? Современный текстовый документ — это вообще контейнер с файлами/объектами.
                    Во-вторых, как я уже говорил, никто не мешает использовать дополнительные аттрибуты для хранения данных, но эти данные не относятся к самому файлу, безусловно. Никто не мешает сохранить картинку в имени файла, но это не делает атрибут «имя файла» — данными в смысле содержимого файла. Т.е это не правильное использование.

                    Опять же, я говорю о своем понимании данных и атрибутов, при котором всё хорошо сходится =)
                    Кстати, пруфлинк про макось вы так и не дали…

                    • +1
                      Опять же, я говорю о своем понимаении данных и атрибутов, при котором всё хорошо сходится =)
                      Ну да, если объявить все факты, которые противоречат вашей точки зрения «несуществующими», то всё сойдётся, конечно.

                      Во-вторых, как я уже говорил, никто не мешает использовать дополнительные аттрибуты для хранения данных, но эти данные не относятся к самому файлу, безусловно. Никто не мешает сохранить картинку в имени файла, но это не делает атрибут «имя файла» — данными в смысле содержимого файла. Т.е это не правильное использование.
                      Тем не менее — это то, для чего потоки были созданы изначально.

                      Кстати, пруфлинк про макось вы так и не дали…
                      Какой именно «пруфлинк» вам нужен? Ссылку на википедию и Руссиновича я дал, вот статьи на windowsecurity и bleepingcomputer, если хотите. Судебного признания от разработчиков NTFS с клятвой на библии у меня нету, но как бы информация про то, откуда взялись ADS — вполне себе широкоизвестный факт. Кстати обратите внимание на само название: ADS — альтернативные потоки данных. Не метаданных.
                      • –1
                        > Ну да, если объявить все факты, которые противоречат вашей точки зрения «несуществующими», то всё сойдётся, конечно.
                        Вы перешли на личности, боюсь, дальнейшее обсуждение в таком ключе не конструктивно. =(

                        > Тем не менее — это то, для чего потоки были созданы изначально.
                        Так я тут уже не спорю. Изначально сделали для дополнительных данных, подключаемых к файлам. Я говорю, что этот факт не меняет моего восприятия данных потоков, как дополнительных мета-данных для файла. Только и всего.

                        > Судебного признания от разработчиков NTFS с клятвой на библии у меня нету
                        Мой комментрий был сделан до того, как я увидел ваш ответ со ссылкой на википедию. Прошу прощения.
                        Но и дальнейшее общение в таком тоне мне не приятно. Sorry. Спасибо за Ваши ссылки и мнение.

                  • 0
                    Если с этими потоками программы умеют работать — это данные, а если полторы калеки — метаданные. Если при копировании на телефон (флешку) и обратно (кста, это отличный способ избавиться от всякого наросшего лишнего веса, иногда применяю, если лениво разбираться с правами и надоедают запросы от системы) потоки сохраняются — это данные, в противном случае это метаданные. Если по почте они отправляются, то данные, иначе — метаданные.
                    • +1
                      Если с этими потоками программы умеют работать — это данные, а если полторы калеки — метаданные.
                      Все программы для MacOS, которые «умеют работать» с данными «умеют работать» и с ресурными данными тоже, разумеется. Иначе там никак.

                      Если при копировании на телефон (флешку) и обратно (кста, это отличный способ избавиться от всякого наросшего лишнего веса, иногда применяю, если лениво разбираться с правами и надоедают запросы от системы) потоки сохраняются — это данные, в противном случае это метаданные. Если по почте они отправляются, то данные, иначе — метаданные.
                      Вау. Как круто. То есть на MacOS вообще нет никаких данных, за исключением архивов StuffItа?

                      И документы, и картинки, и целые журналы — это всё, вообще всё — метаданные? Если их по почте отослать в неархивированном виде, то они после этого уже не откроются, знаете ли…
                      • 0
                        А не было речи про макось, только про винду. А там несколько сложно с этим.
                        Задумка может и была такой, но по факту пока ничего не получилось.
                        • 0
                          Задумка может и была такой, но по факту пока ничего не получилось.
                          Что значит не получилось? Любой MacOS файл, который записывался когда-нибудь на Windows NT сервер (а первое время Windows NT только как сервер и использовалась!) был так устроент.

                          Только позже, сильно-сильно позже, через десять с лишним лет «потоки» начали использоваться в NTFS для каких-то других целей.
            • 0
              А про «ради MacOS» — сможете пруф дать?
              Если честно пруф мне искать лень (давно это было, ещё до того, как web появился), но Wikipedia про это пишет со ссылками на Руссиновича.
              • 0
                Спасибо, вполне достаточно. Руссиновича проверять не будем, достаточно авторитетно =) Но я, тем не менее, не вижу противоречий. Да, дополнительный поток хранит дополнительные данные, но это другие данные, не являющиеся непосредственно частью исходного файла. Я понял, что вы смотрите на это несколько под «другим углом». Сказать какой взгляд более правильный, наверное, нельзя.
                • 0
                  Да, дополнительный поток хранит дополнительные данные, но это другие данные, не являющиеся непосредственно частью исходного файла.
                  Это с какого перепугу?

                  Я понял, что вы смотрите на это несколько под «другим углом». Сказать какой взгляд более правильный, наверное, нельзя.
                  Я вас, честно говоря, не понимаю. Вот смотрите. Возьмите любую программу для MacOS. Там будет в одном потоке храниться структура диалогового окна, а в другом — функции работы с ними.

                  И тут приходите вы, такой весь в белом и говорите: вот то, что написали программисты — это важно, это нужно, это — данные. А вот то, над чем работали дизайнеры, переводчики художники — это всё фигня на постном масле и ценности не имеет. Это — не данные. Извините, но мне, условно говоря, за дизайнеров обидно. И художников.
        • +2
          NTFS streams всё же не метаданные в общем случае (хотя и часто используются в качестве таковых, за отсутствием лучшего варианта), просто парадигма мышления у разработчиков и пользователей ещё не сменилась :)
          • 0
            просто парадигма мышления у разработчиков и пользователей ещё не сменилась :)
            Как раз сменилась :-)

            В прародителе (в MacOS) от идеи потоков давно отказались. NeXTSTEP, MacOS X, iOS испольщуют бандлы. А в Windows туда придумали всякие метаданные пихать.

            Но при этом подавляющее большинство программ могут с ними работать! Туда можно положить и текстовый файл и картинку, даже исполняемый файл, как я уже писал — и все ваши Word'ы и Notepad'ы, Photoshop'ы и Media Player'ы смогут их открыть и использовать.

            Это пользователя, на самом деле, зависит больше, чем от программы, просто некоторые программы могут использовать дополнительные потоки без явного желания пользователя…
  • 0
    Году в 2000-м брал какой-нибудь exe-шник, менял расширение на txt и в блокноте менял один из символов на другой, сохранял файл, затем отменял изменение и сохранял опять. Менял расширение обратно на exe. Файл не запускался с ошибкой «access violation at address». Побайтово сравнивал файл с исходным (в самописной программе), отличий не было. Если же файл изменял не в блокноте, а с помощью кода, то файл запускался. Догадывался, что не запускается из-за флагов, но интернета тогда не было, так что не знал как добраться до флагов, а в книгах, которые у меня были, об этом не писалось.
    • +1
      … а потом в 2001 году вышла XP с NTFS by default, и я проснулся.
      Я к тому, что ошибки ваши были явно связаны не с флагами, а с блокнотом.
      • 0
        Не понял насчет блокнота. Поясните, если не затруднит.
        • +4
          Блокнот не умеет работать с бинарными (ака «не текстовыми») файлами, и при сохранении портит другие участки файла.
          • 0
            Ну так я потому и сверял файлы побайтово, чтобы избежать этого. Тела файлов полностью совпадали.
            • 0
              А вы как файл открывали программно?
              FILE* fin = fopen("rb", "myfile.exe");
              

              Помню, в каких-то реализациях 'b' в режиме требовалась для правильной работы с бинарными файлами.
              • 0
                Я тогда на паскале учился программировать, там не нужно было указывать режимы. Вероятно писал что-то вроде этого (точнее уже не помню):
                var
                f: file;
                Assign(f, "myfile.exe");
                BlockRead(f, x, count);
                
    • 0
      Знакомая хохма — см. http://habrahabr.ru/post/264081/
  • +14
    Это ещё фигня. Вот я однажды (дай бог памяти, в 2004 году) отловил ошибку в фирмвари дисков Fujitsu. Переписка с инженером у меня сохранена, но она была на английском, а переводить, конечно, лень — но в принципе могу разродиться на статью, если почтенная публика попросит.
    • +6
      Таки сподобился: http://habrahabr.ru/post/274235/
  • +4
    Как бы не так! WinMerge врёт
    WinMerge не врет — он сравнивает содержимое файла, а оно, как раз, идентично.
    • 0
      WinMerge мог бы выдавать ворнинг или иметь в опциях галочку, позволяющую сравнивать и альтернативные потоки данных. Люди ведь для чего сравнивают файлы — чтобы понять почему «тут работает, а тут уже нет». В данном случае WinMerge с этой задачей не справился.
      • –1
        Это утилита сравнения содержимого файлов, а не файлов на физ. уровне или уровне системы. Поэтому никаких варнингов она кидать не должна. И со своей работой она отлично справилась.

        Нужно сравнение на других уровнях — используйте для этого инструмент сравнения файлов, а не содержимого файлов. Такие утилиты сравнивает и методанные и, например, атрибуты файлов. Ибо в этом-же контексте файл с ReadOnly != файлу без него при одинаковом содержимом.
        • 0
          И со своей работой она отлично справилась.

          Нет, ну если мы ставим вопрос «Решает ли WinMerge задачу сравнения содержимого файлов?», то ответ «конечно, решает». А если мы ставим вопрос «Помогает ли WinMerge понять, чем отличаются файлы с точки зрения выяснить почему с одним всё работает, а с другим — нет?» то ответ «не помогает».

          Не знаю, кому нужно узнать разницу в содержимом файлов «просто так», обычно нужно узнать «что изменилось и сломалось?»
          • 0
            т.е. Вас не смущает, что Вы использовали утилиту, которая не предназначена для решения вашей задачи, и теперь ее ругаете? :)

            Вас же не смущает, что калькулятор не может видео проигрывать?
            Вы ведь за это калькулятор ругать не будете?

            Не знаю, кому нужно узнать разницу в содержимом файлов «просто так», обычно нужно узнать «что изменилось и сломалось?»
            Обычно нужно узнать, что изменилось в содержимом файла.

            Например, понять, что изменилось в двух текстовых файлах — это крайне распространенная задача. А вот как раз копаться в метаданных — крайне редкая.
            • +1
              Ну Вы посмотрите что написано на сайте WinMerge в разделе описания функционала:
              «WinMerge is an Open Source differencing and merging tool for Windows. WinMerge can compare both folders and files, presenting differences in a visual text format that is easy to understand and handle.»


              Видите, файлы она обещает сравнивать, а не содержимое файлов.
  • 0
    .Net Framework позволяет создавать сборки из нескольких файлов. Инструментом является утилита assembly linker. Это альтернатива «ручной» архивации. Конечно, трудно сказать что лучше конкретно в вашем случае.
    • 0
      Всё хорошо, пока мы остаёмся в рамках .NET. А вот если плагину нужно включить, скажем, исполняемый файл какой-то утилиты, который за собой тянет ещё пару неуправляемых библиотек и ресурсов — проще это оформить архивом, чем пытаться паковать в .NETовские сборки.
  • +1
    Находил такой прикол, когда ставил однажды Synaptics-тачпад-драйвер на ноуте.
    Распакованный виндовой утилитой драйвер после инсталляции задавал дурацкие вопросы при старте своих утилит.
    Сразу стало понятно, кто виноват.
    После этого случая я начал делать финт ушами на домашнем компе: gpedit.msc — Конфигурация пользователя — Административные шаблоны — Компоненты Windows — Диспетчер вложений — Удаление сведений о зоне происхождения вложений — Включить — Ок.
    А то эти вопросы дурные ни к чему на однопользовательском компе. А на группе файлов этот признак не убирается (пачкой), по одному сиди разблокируй (Win 7).
    • 0
      Выше уже привели батник для пакетного «убирания» флага.
      • 0
        Мой путь приводит к «несозданию» (да, да, к автоудалению) этого флага в принципе, и убирать ничего не требуется.
        • 0
          Да, я то знаю.
          Это в ответ на «А на группе файлов этот признак не убирается (пачкой), по одному сиди разблокируй (Win 7)».
          С помощью батника можно не по одному файлу тыкать, а сразу всем файлам снять признак.
          • 0
            Да, есть такое.
  • 0
    Очень знакомая проблема для тех, кто работает со SCADA WinCC от Siemens.
    Если просто так скопировать проект на другой компьютер, то скорее всего он не заработает. Если же пользоваться архиватором из Step-7 либо утилитой project duplicator, то всё ок.
    Видимо, причина та же.
  • 0
    Такая же беда уже лет десять творится с chm-файлами, в которых при наличии этой пометки отображается только оглавление, а страницы — пустые. И, если не знаешь, в чем тут дело — замучишься гадать, почему не отображается содержимое. Хотя могли бы вместо «unable to display» (или что там еще, не помню уже) отображать что-нибудь вроде «отображение запрещено из соображений безопасности, для разблокировки сделайте то-то».
  • 0
    Интересно, Red Star отслеживает путь распространения файла в расширенных атрибутах, или что-то своё навелосипедили.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка