Slow FileClose () вызвано MsMpEng при разархивировании исполняемых файлов - PullRequest
0 голосов
/ 27 марта 2020

Я сталкиваюсь с огромным замедлением при распаковке исполняемых файлов из моего приложения. Я упростил его до извлечения из памяти и минимализма c CreateFile, отдельных вызовов WriteFile и CloseHandle.

Когда происходит вызов CloseHandle, MsMpEng (Windows антивирус) сканирует в течение нескольких секунд (всего 40 секунд)

При разархивировании одинаковых файлов с помощью 7zip MsMpEng практически не оказывает влияния на производительность (1-2 секунды). При разархивировании со старым unzip.exe (5.51) наблюдается очень заметное использование процессора MsMpEng (7-8 секунд), но намного меньше, чем в моем случае. Проверка файлов с помощью антивируса Windows вручную выполняется очень быстро.

  • Я попытался создать файл в эксклюзивном режиме, не влияющий на производительность.
  • Я попытался извлечь файл под нейтральным именем. и переименование, не влияющее на производительность.
  • Я пытался заменить первые 16 КБ файлов нулями, в этом случае не происходит значительного использования MsMpEng. Но как только я снова открываю файлы для записи заголовка 16 КБ, MsMpEng снова занимает несколько секунд.
  • Я посмотрел исходный код unzip.exe и не увидел ничего особенного.
  • Я попытался пропустить вызов FileClose и «утечь» дескриптор файла, при этом я могу извлечь все очень быстро, но при закрытии приложения очень долгая пауза (когда Windows закрывает дескрипторы файла, я предположим)

Сейчас у меня заканчиваются идеи относительно того, что может вызвать плохое поведение MsMpEng ... почему unzip.exe не так подвержен уязвимости и как 7zip избегает его?

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

var buf := z.UnZip(i);
var h := CreateFile(PChar(fileName), GENERIC_READ or GENERIC_WRITE,
                    0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
WriteFile(h, buf[1], Length(buf), nb, nil);
Assert(nb = Length(buf));
CloseHandle(h);   // <-------- this is the slow part, and only it
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...