Win32: предложения по тестированию проявленного приложения и развертыванию

Начиная с Windows Vista, Microsoft добавила класс прокладок совместимости, которые позволяют приложению, которое предполагает, что оно имеет административный доступ к файлам и реестру, продолжать работу. функция.

Другими словами: приложение, вызвавшее сбой в Windows XP, будет работать в Windows Vista.

Эти исправления ошибок, предоставленные ОС, можно отключить, добавив раздел в манифест приложения, объявив, что приложение должно работать asInvoker:

<!-- Disable Windows Vista standard user compatability heuristics -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
   <security>
      <requestedPrivileges>
         <requestedExecutionLevel level="asInvoker"/>
      </requestedPrivileges>
   </security>
</trustInfo>

В идеале разработчик должен протестировать свое приложение, чтобы убедиться, что оно не требует (без нужды) административных привилегий. Чтобы проверить это, мне нужно было бы манифестировать его как Invoker.

Но когда дело доходит до дела, я не собираюсь выпускать приложение для клиента, представленного asInvoker. Если я что-то пропустил, я не хочу, чтобы это повлияло на пользователя. я хочу, чтобы операционная система Microsoft исправила мои ошибки. Проблема с этим решением:

  • я должен изменить manfiest перед выпуском
  • я никогда не узнаю о вещах, которые пропустил, потому что они просто работают в Windows Vista.

Аналогичная головоломка возникает с поддерживаемой ОС Windows 7< /strong> манифестировать целиком. Вы можете добавить в приложение манифест, указывающий, для какой версии Windows вы были разработаны и протестированы:

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
   <application> 
      <!--The ID below indicates application support for Windows Vista -->
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
      <!--The ID below indicates application support for Windows 7 -->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
   </application> 
</compatibility>

В случае элементов supportedOS операционная система заранее знает, для какой ОС вы были разработаны. Это поместит ваше приложение в контекст Windows Vista, если вы не укажете, что поддерживаете Windows 7:

alt text
(источник: msdn.com)

Это действие аналогично запуску приложения в каком-либо режиме совместимости, например:

  • Windows Server 2008 (пакет обновления 1)
  • Windows Vista (пакет обновления 2)
  • Windows Vista (пакет обновления 1)
  • Виндоус виста
  • Windows Server 2003 (пакет обновления 1)
  • Windows XP (пакет обновлений 2)
  • Windows 2000
  • Windows NT 4.0 (пакет обновления 5)
  • Windows 98/Windows Me
  • Windows 95

где вы получите набор прокладок совместимости, а Windows будет эмулировать старое недокументированное поведение, чтобы помочь вашему приложению избежать сбоя, когда оно зависело от этого недокументированного поведения.

пример прокладок совместимости, которые предоставляет Windows 7 для приложения, работающего в контексте Windows Vista:

  • RPC будет использовать старый частный пул потоков, а не пул потоков ОС.
  • вы сможете заблокировать основной видеобуфер рабочего стола
  • вы сможете Blit в основной видеобуфер рабочего стола без указания окна отсечения
  • вы будете уязвимы для состояния гонки GetOverlappedResult (если вы от него зависели)
  • вы по-прежнему будете получать меры по смягчению последствий Program Compatibilty Assistant (PCA)

И еще раз, чтобы правильно протестировать мое приложение в Windows 7, я должен добавить запись манифеста supportsOS. Но опять же, я не поставлю приложение с этим флагом, потому что не хочу терять преимущества этих прокладок (например, PCA). И, опять же, если в приложении есть проблемы, которые были исправлены, потому что оно работало в контексте Vista: я никогда не узнаю об этом от наших клиентов, потому что приложение просто работает.


Мысли? Руководство? Лучшие практики?


person Ian Boyd    schedule 10.11.2009    source источник
comment
Это очень хороший вопрос.   -  person i_am_jorf    schedule 10.11.2009
comment
Если вы пропустите манифест (asinvoker), вы НЕ будете уведомлены о проблеме. Windows просто вызовет свою эвристику UAC и молча использует виртуальные папки и виртуальные кусты реестра для выполнения ошибочных запросов вашего приложения. AsInvoker на самом деле приведет к тому, что ваше приложение получит ошибку, если вы попытаетесь превысить свой рейтинг безопасности, и, следовательно, вы сможете найти и отладить его. У вас есть концепция задом наперед, AFAICT   -  person Mordachai    schedule 02.12.2009
comment
Мордахай: Да, это то, о чем я (думал) говорит мой вопрос. Если у меня нет манифеста, Windows исправит проблемы. Если я добавлю манифест, эвристика отключена.   -  person Ian Boyd    schedule 03.12.2009
comment
Чтобы я мог проверить это, мне нужно было бы проявить его как Invoker. я проявляю это во время тестирования, чтобы видеть ошибки (потому что эвристика отключена). я не собираюсь выпускать приложение заказчику, представленному как Invoker. Если я что-то пропустил, я не хочу, чтобы пользователь пострадал. И я убираю запись манифеста для выпуска.   -  person Ian Boyd    schedule 03.12.2009


Ответы (3)


я не собираюсь выпускать приложение заказчику, представленному как Invoker. Если я что-то пропустил, я не хочу, чтобы пользователь пострадал.

Я думаю, что это плохой подход. Мой совет — правильно манифестировать с самого начала и тестировать то, что вы развертываете.

Microsoft не собирается из кожи вон лезть ради всеобщей совместимости. Они будут нацелены на наиболее распространенные и серьезные ошибки, допущенные крупнейшими поставщиками. Если вы пропустите какую-то небольшую проблему, вероятность того, что они предоставят прокладку в будущем, мала.

Каждый раз, когда Microsoft добавляет прокладку совместимости, мы все расплачиваемся. Есть API-интерфейсы, которые не работают должным образом, потому что им приходилось обрабатывать некоторые случаи безмозглым способом, чтобы добиться совместимости с чьей-то ошибкой. Это означает длительные и болезненные сеансы отладки, это означает продираться через более длинную (или менее полную) документацию, и это означает небольшую неэффективность ОС для всех. Это также означает, что разработчики Windows тратят время на исправление чужих ошибок вместо того, чтобы улучшать ОС.

Иногда эти изменения совместимости являются большими ударами по разработчикам, которые делают это правильно. Многие приложения неправильно обрабатывают высокое значение DPI, поэтому — во имя совместимости — Vista предполагает, что никакие приложения не обрабатывают его правильно (если только они явно не заявляют об обратном). Vista применяет масштабирование пользовательского интерфейса. Приложения, не поддерживающие высокое разрешение, получают улучшенные (но неоптимальные) результаты. Приложения, которые обрабатывали high_DPI, получают неудовлетворительные результаты. (Клиенты, использовавшие хорошие приложения, видят, что они становятся хуже, когда переходят на Vista, и обвиняют Microsoft.) Разработчики, не уплатившие налоги, получают помощь от Microsoft, остальные (включая Microsoft) подвергаются наказанию. Единственный способ избежать этого — заставить всех платить налоги.

В общем, Microsoft все лучше и лучше делает эти прокладки совместимости более целенаправленными (хотя Vista была довольно резкой). Тем не менее, у каждого есть небольшая стоимость.

Следуйте лучшим практикам во время разработки. Протестируйте то, что вы планируете развернуть. Если что-то выйдет из строя, Microsoft может исправить это за вас. В противном случае вам, возможно, придется выпустить обновление. Это лучше, чем наказание всех, потому что некоторые разработчики поступили неправильно.

person Adrian McCarthy    schedule 12.11.2009
comment
Я согласен со всем, что ты сказал. Но если программное обеспечение дает сбой из-за функции, которую я специально выбрал, значит, я ее сломал. я не думаю, что в Windows должны быть прокладки, я думаю, что приложения должны ломаться, и компания обязана исправлять их бесплатно для всех своих пользователей. Если компания не хочет его обновлять, компания потеряла исходный код или компания не существует, то кто-то все равно должен это исправить. - person Ian Boyd; 12.11.2009

AsInvoker — правильный способ распространения вашего приложения!!!

Все, что говорит, запускается с учетными данными пользователя. Здесь не сказано «сделай что-нибудь скрытное» или «используй права администратора».

Без этого манифеста вы маркируете свое приложение как «Я не знаю об UAC, поэтому, пожалуйста, предоставьте мне любые хаки, которые вам нужны, чтобы я все еще мог работать в любой системе, в которой есть UAC».

Но если ваше приложение не пытается делать вещи только для администратора - и вы можете легко проверить это, просто войдя в систему как обычный пользователь, а затем запустив свое приложение и наблюдая за сбоями - тогда AsInvoker абсолютно прав.

Это может помочь вам разобраться с этим: Исследование программистом пользователя Vista Контроль аккаунта

person Mordachai    schedule 01.12.2009
comment
Мое приложение (намеренно) не делает ничего, что только для администратора. Это также относится почти ко всем приложениям. И именно поэтому многие приложения терпят неудачу при работе от имени настоящего стандартного пользователя. Вот почему Microsoft создала стандартную эвристику пользователя в Vista. - person Ian Boyd; 03.12.2009
comment
и вы можете легко проверить это, просто войдя в систему как обычный пользователь, а затем запустив приложение и наблюдая за сбоями. Это не так; это не так просто. Иногда бывают труднодоступные пути кода, которые мое собственное тестирование может никогда не увидеть. Если бы это было легко, то все программы были бы безглючны, потому что все возможные сценарии уже проверены. - person Ian Boyd; 03.12.2009
comment
И, наконец, обратите особое внимание на строку в моем первоначальном вопросе: «Если я что-то пропустил... Если я что-то пропустил, я хочу, чтобы приложение продолжало работать». Ведь в XP работало - а в Висте вдруг выходит из строя. Глупая Виста, говорит заказчик. И вдруг клиент отказывается перейти на Vista, потому что это сломало наше важное бизнес-приложение. - person Ian Boyd; 03.12.2009
comment
Я слышу, что вы говорите: в идеале вы хотели бы, чтобы MS использовала любые прокладки совместимости, которые она может придумать, чтобы гарантировать, что ваше приложение продолжает работать без проблем на любой новой версии ОС, которую они делают (или с пакетом обновления). ). Однако эвристика UAC приводит к тому, что многие программы плохо понимаются и работают правильно. Мне приходилось поддерживать многих пользователей устаревших приложений, которые работали неправильно именно из-за прокладок совместимости MS, а также из-за того, как работают виртуализированный реестр и файловая система. Пометка вашего приложения как предшествующего Vista не изолирует вас от проблем - person Mordachai; 03.12.2009
comment
Это просто меняет то, с какими проблемами вы сталкиваетесь. Простой пример: программа хранит настройки в HKLM\Software\company\... Это работало под XP и т. д. Пользователь обновился до Vista. Программное обеспечение продолжает работать и показывать свои текущие настройки ... ПОКА пользователь не изменит настройку. В этот момент программное обеспечение пытается записать в HKLM\Software\company\... и в дело вступает виртуализация UAC - создает новый виртуализированный ключ для приложения, в которое оно записывает, и теперь ЭТО ЕДИНСТВЕННЫЙ КЛЮЧ, который может видеть приложение. по этому адресу (все другие связанные настройки исчезли из-за того, что теперь они скрыты за виртуальным ключом. - person Mordachai; 03.12.2009
comment
Эта же проблема возникает для папок в файловой системе. И есть еще более тонкие проблемы, возникающие из-за прокладок MS. Итог: их прокладки хуже, чем полезны. В большинстве случаев ваше приложение должно было делать то, что оно запрашивало. Если под ним делается что-то ужасно умное, никто не может догадаться, действительно ли оно было достаточно умным, чтобы работать правильно. По моему опыту: почти никогда. MS ватин в среднем. сильно сосет. - person Mordachai; 03.12.2009

Насколько я понимаю, вместо предоставления файла манифеста с вашим дистрибутивом его также можно напрямую связать с вашим EXE-файлом, добавив следующую команду в файл ресурсов вашего приложения: [1,2].

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "YourApp.exe.manifest"

Отдельный файл манифеста в каталоге, содержащем EXE-файл, может переопределить этот связанный манифест, но это остается на усмотрение клиента. Вы бы не поставляли его.

Теперь компилятор ресурсов "RC" от Microsoft принимает директивы препроцессора, такие как #ifdef [3]. Это означает, что вы можете указать своей Visual Studio иметь две отдельные цели сборки, определяющие разные определения препроцессора, такие как TESTING и DEPLOYMENT.

Затем достаточно использовать директивы #ifdef для использования двух разных файлов манифеста для целей тестирования и развертывания, и вы можете редактировать файлы манифеста по своему усмотрению. Это решит вашу проблему?

[1] http://msdn.microsoft.com/en-us/library/ms997646.aspx
[2] http://doc.ddart.net/xmlsdk/htm/sdk_dependencies_5wvi.htm
[3] http://msdn.microsoft.com/en-us/library/aa381033%28VS.85%29.aspx

person littlegreen    schedule 11.11.2009
comment
Я думал о внешнем манифесте. Но, начиная с Windows Server 2003 и новее, любой внутренний манифест предпочтительнее файла .manifest (blogs.msdn.com/junfeng/archive/2009/05/11/) - person Ian Boyd; 11.11.2009
comment
Что ж, это даже хорошая новость, потому что описанное выше решение реализовано с помощью внутреннего манифеста, а не внешнего. Боюсь, я недостаточно ясно выразился... должен ли я объяснить это лучше? - person littlegreen; 12.11.2009
comment
Отдельный файл манифеста в каталоге, содержащем EXE-файл, не может переопределить связанный манифест. я должен иметь возможность добавить определение, чтобы не включать манифест, делая программное обеспечение с использованием внешнего манифеста. - person Ian Boyd; 12.11.2009
comment
Действительно, вы правы: другой способ — использовать #ifdef для выбора между внутренним и НЕТ манифестом, то есть внешним манифестом, а не между двумя внутренними манифестами. Эффект был бы тот же. - person littlegreen; 13.11.2009