Отладка на кофейной гуще.
При определённой сноровке, можно отлаживать код прямо из любимого почтового клиента. На днях пришло письмо с вопросом. Некоторое приложение, будучи установленным в каталог отличный от “Program Files”, при запуске вызывало появление окна UAC с требованием повысить привилегии. Приложение работало нормально, в случае, если оно было установлено в “Program Files”. Как такое может быть?
Надо сказать, что разработчики подсистем Windows, которые обеспечивают обратную совместимость, вплотную приблизились к созданию искусственного интеллекта.
Windows умеет распознавать и, что самое главное, исправлять на ходу многие некорректные с точки зрения системы действия программ. Заметная часть этого «интеллекта» задействована для обеспечения совместимости с приложениями, которые не умеют работать без прав локального администратора, т.е. при включенном UAC.
Предположение, что программа делает что-то нехорошее, – пытается создать файл в «Program Files» например, вскоре частично подтвердилось. Автор приложения обнаружил, что оно пытается создать ключ реестра “HKEY_CLASSES_ROOT\.foobar”. Интересная особенность всех ключей в ветке “HKEY_CLASSES_ROOT” состоит в том, что эти ключи … не существуют. “HKEY_CLASSES_ROOT” – это виртуальный ключ, объединение двух других ключей: “HKEY_LOCAL_MACHINE\Software\Classes” и “HKEY_CURRENT_USER\Software\Classes”. Соответственно попытка создать ключ “HKEY_CLASSES_ROOT\.foobar” может, при определённых условиях, быть интерпретирована как попытка создания “HKEY_LOCAL_MACHINE\Software\Classes\.foobar”, что уже попахивает криминалом.
Далее, существует такая штука как LUA Virtualization. Если коротко, то это механизм как бы позволяющий приложению писать в ключи и каталоги, защищенные от записи. На самом деле, система на лету подменяет оригинальный ключ доступной на запись копией, локальной для этого конкретного приложения.
Соединив эти три кусочка информации, можно примерно догадаться что произошло. Хотя точно сказать, что именно произошло, я не берусь. Скорее всего, программа попыталась создать “HKEY_LOCAL_MACHINE\Software\Classes\.foobar”. Эта попытка была перехвачена механизмом LUA Virtualization. В случае, когда исполняемый файл находился в “Program Files”, механизм виртуализации делал свое черное дело, подсовывая приложению локальную копию ключа. В другом случае виртуализация не срабатывала, приводя к тому, что запрещенная операция перехватывалась уже логикой активации UAC.
Очень печальная перспектива. Сложные системы порождают сложные ошибки. Искусственный интеллект не получится, а вот технологию “искусственной тупости” создать вполне удастся.
А все эти приколы операционной системы: их отключить можно? Глобально? Ведь иначе пожизненно будут создаваться программы, не работающие без подобного “искусственного интеллекта”.
Насколько же проще работать разработчикам того же FreeBSD: все сторонние программы в дереве портов, в исходниках. Поменялось API – перекомпилял, при необходимости взял и добавил патчей.
У меня иногда создается впечатление, что закрытие исходников создает больше затрат, чем прибыль, которую приносит от продаж.
Подлая фича этот virtualization, надо сказать. Несколько неожиданно обнаружить, что каждая программа видит свой образ диска C. Лучше бы он явно включался для проблемного софта, которого в моей практике очень и очень немного.
Можно. Если Вы хотите отключить это для Вашей программы, то просто добавте манифест, декларирующий совместимость с Vista. Если вы хотите сделать это для сторонней программы, или для всех программ, то это тоже возможно, но вот вопрос – что Вы будете делать с этими неработающими программами?
Виртуализация, нужно сказать, включается только для проблемного софта. Она включается только тогда, когда приложение делает попытку записать в read-only ключ или каталог. Т.е. софт уже делает гадость. И вопрос в том дать ли программе упасть или позволить её работать как ни в чем не бывало.
@Not a kernel guy
Нужно ли считать любой file manager по определению проблемным софтом? А source code control client? В общем, любую преднамеренную и легитимную запись в program files?
Я-то очень хотел увидеть запрос на elevation. Что особенно цинично, иногда он таки показывается! И в этом случае файлы пишутся совсем в другое место =)
Кстати, интересно, как можно рассчитывать на сокращение криво написанного софта, если его кривость втихаря скрывается даже от авторов? )
Файловый менеджер – хороший пример когда виртуализация вредна, а вот source code control client – нет. Ему как раз в Program Files писать незачем. Тем не менее, у этой палки два конца:
1. С одной стороны правильно написанный софт не должен создавать файлы в Program Files и делать прочие гадости. И правильная OS не должна позволять это делать.
2. С другой стороны пользователем софта интересует только то, работает ли софт или нет. Vista – очень показательный пример. Стоило чуть-чуть закрутить гайки, так сколько возмущенных криков раздалось со всех сторон.
Так что без обратной совместимости (пусть даже ценой таких трюков) – никуда. Даже если это не нравиться разработчикам. А у разработчиков всегда есть возможность отключить настройки совместимости.
Еще раз подчеркну, у разработчиков всегда есть возможность отключить настройки совместимости.
@Not a kernel guy
Еще раз подчеркну, у разработчиков всегда есть возможность отключить настройки совместимости.
Если не будут закручивать гайки, совместимого софта будет мало.
К примеру, все же могут по улице строем ходить. Однако же не ходят.
Да и такая виртуализация раздражает безмерно – уже даже ощущение, что система в основном делает хоть что-то понятное, пропадает.
А почему нельзя выводить для плохих программ неприятное предупреждение о необходимости виртуализации? В том же стиле, что и UAC, с подробным объяснением что случилось, и кто виноват – кому писать жалобы?
Вот почему: http://blogs.msdn.com/cjacks/archive/2008/12/11/you-can-t-fix-application-compatibility-problems-with-dialog-boxes.aspx
@Not a kernel guy
Я имел ввиду, что показать ровно один раз за жизнь системы и программы в ней уведомление о том, что включается режим совместимости. С одной кнопкой ОК. Или в заголовке окна этой программы поставить галку/кнопку/большой красный флаг – что угодно. Лишь бы, хоть как-то обозначить включение виртуальности.
Иначе, если пользуешься этой программой, никак не ожидаешь каких-либо подвохов.
А диалоговые окна при каждом запуске конечно …бут кого угодно.
———————–
В общем, как обычно, нет никаких проблем сделать любую систему непонятной. А вот сделать так, чтобы система была понятной как топор и делала всё, что нужно – реально круто.
И эта виртуальная фс – очередное тому доказательство.
Это единственное сообщение точно также будет проигнорированло и забыто срузу после клка на OK. Проблема даже не в этом, пользователю в 99% случаев фиолетов тот факт, что программа пишет в Program Files.
Хоть как-то виртуальность обозначена. В Task Manager есть соответствующая колонка. Кроме того, в заголовок окна хочет попасть слишком много народу. Например полезно знать 32-х или 64-х битное прилодение запущено. И кучу других вещей. Что все это запихать в заголовок?
Кто бы спорил.
Мы говорим немного о разных видах пользователей: “простых” пользователях и разработчиках сторонних программ под MS Windows. Первым действительно абсолютно фиолетово, пишет кто Program Files или нет. Вторым же относительно нефиолетово, насколько “правильно” их программа взаимодействует с ОС. Всё-таки нормальный человек должен чуточку беспокоиться о своём детище.
Соответственно, задача состоит в том, чтобы минимально беспокоя “простых” пользователей, донести до максимального числа разработчиков культуру написания программ под MS Windows. Проблема в том, что и “простые” пользователи, и разработчики используют одну и ту же систему.
Поэтому предлагается сделать штуку, которая простым пользователем будет проигнорирована на уровне спинного мозга, но будет воспринята разработчиком в отношении ЕГО собственной программы.
Может быть это нужно делать на уровне отладчика в Visual Studio (может быть там уже и есть). Но вряд ли: ведь если неустановленная программа пишет в свой каталог, ничего критического не получается.
————-
За Task Manager спасибо. Не знал. Причём без Вашей заметки я бы никогда не догадался, виртуализация чего отмечается в колонке Virtualization
Разработчики в подавляющем большинстве случаев являются теми же самыми “простыми” пользователями. В том числе в процессе работы над своей программой. Они запускают компилятор и другой софт, который может делать что-то нехорошее.
Кроме того, то, что они используют одну и ту же систему на самом деле хорошо. Ситуация когда программа тестируется в слегка отличном от production окружении с завидным постоянством генерирует “неуловимые” ошибки.
Это очень и очень плохо. Во-первых, мы тренируем пользователей не замечать сообщения. Ситуация уже никуда не годится. Добавляя “ненужных” сообщений мы только делаем хуже. Во-вторых, сообщения должны быть actionable. Т.е. сообщение должно явно говорить что пользователю делать. В этой же ситуации пользователь не может ничего сделать. Информационные сообщения только раздражают. В-третьих, если разработчик заботится о свое программе, он ВСЕГДА может задекларировать свою совместимость с нужной версией OS. Это очень просто и описано в MSDN. В-четвертых, разработчики не единственная группа пользователей, которая может нуждаться в подсказках такого рода. Что Вы скажете, если для того, чтобы, скажем, бухгалтера знали о какой-то особенности системы, мы будем показывать сообщение всем пользователям запускающим Internet Explorer? Ситуация по числу целевых и всех пользователей аналогичная.
Ну вот я пошел, создал в Visual Studio программу, пытающуюся создать ключ HKEY_LOCAL_MACHINE\Software\FooBar. Запустил и получил Access Denied. Это значит, что при настройках по-умолчанию виртуализация не срабатывает. Я, к сожалению, не знаю всех параметров, которые при этом учитываются, но знаю что список довольно длинный. И длина списка связана иместо с тем фактом, что виртуализироваться должны только “старые” приложения.
Да. Паршиво получается.