среда, 20 марта 2013 г.

Странное поведение прикладной программы

Довелось недавно обновить на работе одну программу. Она установилась нормально, но при работе стали появляться непонятные сообщения, не все функции работали должным образом.
Выяснению причин этого и приведению программы в работоспособное состояние посвящена эта статья.
Заодно показан способ решения проблем с помощью программы "Process Monitor".

Довелось на днях обновить на нашем предприятии одну нашу внутрикорпоративную программу. Имя вам ничего не скажет, поэтому я буду называть ее - программа.
Ставилась она очень просто. Надо было распаковать ее из архива и скопировать на место предыдущей версии. Чтобы пути были одинаковы. Так сказали программисты, которые ее написали. И поскольку находились они далеко, этим мегапростым делом пришлось заниматься мне.
Старая версия программы находилась в "C:\ProgramFolder". Я переименовал ее в "C:\ProgramFolder.old". А в старое место  "ProgramFolder" скопировал новую версию программы. Запустил. Стартовала она хорошо. Оператор набрал данные. Нажал кнопку сохранить.
И тут появилось сообщение, что не все данные сохранены. И предложение сохранить их заново. Заново так заново. Согласились. Снова то же сообщение что не все данные сохранены с предложением сохранить заново. После десяти раз я таки догадался, что дело пошло по замкнутому кругу. Я это прервал и с оператором посмотрели все ли данные сохранились. Выяснилось, что не сохранилось ничего.

Мои телодвижения

  1. Свободного места на C: было немеряно, поэтому эту версию пришлось откинуть.
  2. Звонок авторам программы. Они советовали какие папки следует почистить, какие сохранить резервные копии. Что удалить, что добавить и где изменить. Ничего не помогало.
  3. Проверил права записи на NTFS в папке программы. И на всякий случай дал полные права. Не помогло.
  4. Наконец я вспомнил о архитекторе ядра Windows Марке Руссиновиче и его наборе утилит Sysinternals. Только на них оставалась надежда.
Вернее я подумал не о всех утилитах, а о "Process Monitor", позволяющей отследить обращения к файлам и реестру.

"Process Monitor" нам поможет

Если вам неинтересно как я возился с монитором процессов, сразу переходите к последним двум абзацам этой главы.
  Итак, я закрыл все программы. Запустил "Process Monitor". Он сразу стал показывать куда лезут все приложения и службы, которые в этот момент были запущены. Поскольку они были мне не интересны, я на каждом процессе нажал правой кнопкой мыши и в выпавшем меню выбрал "Exclude" для исключения этого процесса. Мне нужно было следить только за проблемной программой. Когда список процессов стал пустым, запустил ее. Прошел все шаги по созданию документа и его сохранению. В тот момент когда появилось сообщение о несохраненных данных я переключился на "Process Monitor" и остановил запись событий по Ctrl-X. Просмотр записанных событий меня обескуражил. Было зарегистрировано несколько сотен тысяч событий и разобраться в них было нереально. Фильтры "Process Monitor" надо было ужесточить.
  Я стер все записанные события. И добавил еще один фильтр сохранять событие только при его не успешном результате, "result is not success". И решил, что меня интересует не все события проблемной программы, а только сохранение ее результатов.
  1. Отключил запись событий в "Process Monitor". 
  2. Запустил проблемную программу и дошел до того момента, когда надо нажать кнопку "Сохранить". 
  3. Включил запись событий процесс монитором. И тут же давлю кнопку "Сохранить" в проблемной программе.
  4. Когда появилось окно с ошибочным сообщением переключаюсь на "Process Monitor" и по Ctrl-X останавливаю запись событий. Их оказалось всего лишь несколько тысяч. Я начал их просмотр с конца, с последнего события.
  Первым делом внимание привлекли поиски Wing32.dll по всем системным и не очень папкам. Поиски в интернете показали что это "Windows High Performance Graphics Library". Поразмыслив решил, что внутрикорпоративная программа не настолько сложна, чтобы ей сильно нужна была высокопроизводительная графическая библиотека. Пошел дальше.
  Вот записано, как проблемная программа что-то читает из своей папки
"C:\ProgramFolder.old" и дальше... Стоп. Назад. Вот оно.

Эврика

  Напоминаю, что в начале я переименовал старую версию программы, добавив к имени ее папки расширение .old. И после этого в то место записал новую версию. А теперь "Process Monitor" ясно показал, что почему-то наша программа полезла в свою старую папку.
  Я перенес старую папку ProgramFolder.old на другой диск. Запустил программу из новой папки. Она нормально стартует, вводятся все данные. Но в момент сохранения появляется окно с ошибкой. Но это другое окно. И другая ошибка. И смысл ее в том, что программа не может прочесть конфигурацию из "C:\Progra~1".
  Несколько раз перечитываю это сообщение, пока до меня доходит, что проблемная программа почему-то использует короткие имена файлов до 8 символов, унаследованные еще со времен до Windows 95. А у меня в C:\ две папки с почти одинаковыми названиями.
  Старая версия в ProgramFolder.old которая соответствует короткому имени Progra~1
  И новая версия в ProgramFolder , соответственно Progra~2
  Понимаю, что где-то в настройках программы надо поменять одно короткое имя на другое. Начинаю Far-ом исследовать папку этой программы. Быстро натыкаюсь на файл с абракадаброй в названии и уже не помню с каким расширением. И нахожу в ней то что искал. Меняю. Запускаю нашу программу. Наконец-то она работает.
  Проверка того что она сохранила показала, что данные сохранены.
  Мы снова победили.
  Позже "Process Monitor" для другого приложения помог мне выяснить где программа хранит данные.