Вопрос: Для реализации той или иной функциональности я часто использую в своих сценариях на JScript и VBScript утилиты, загруженные из Internet. Недавно я установил Windows XP Service Pack 2 (SP2) и теперь, когда в сценарии с помощью метода Run объекта WshShell вызывается какая-либо из этих утилит, на экране появляется диалоговое окно предупреждения системы безопасности, в котором спрашивается, действительно ли следует запустить данную программу. На компьютерах с Windows XP SP1 и Windows 2000 такая проблема не возникала. Почему это происходит? Можно ли как-то исправить данную ситуацию?

Ответ на Ваш первый вопрос заключается в реализованной в Windows XP SP2 новой технологии, называемой Attachment Manager, или Attachment Execution Services. Описание данной технологии содержится в статье Microsoft "Description of how the Attachment Manager works in Windows XP Service Pack 2" (http://support.microsoft.com/?kbid=883260). В настоящее время прикладной интерфейс Attachment Manager API используют такие компоненты как Microsoft Internet Explorer (IE), Outlook Express и Windows Messenger. Вообще говоря, упомянутая Вами проблема рассмотрена в статье "The Open File - Security Warning dialog box is displayed when you try to silently install a hotfix or an update by using a Visual Basic script in Windows XP Service Pack 2" (http://support.microsoft.com/?kbid=889815). Причем нужно отметить (хотя из заголовка статьи это не очевидно), что данная проблема касается не только исправлений (hotfix), обновлений (update) и сценариев на VBScript.

При сохранении вложения или загрузке файла Attachment Manager использует для проверки источника вложения (или загружаемого файла) текущие настройки зоны Internet (Internet zone). В процессе сохранения файла на дисковом разделе NTFS компонент Attachment Manager добавляет к загруженному файлу альтернативный поток данных, именуемый Zone.Identifier, который идентифицирует ту зону, откуда был загружен файл. Если Вы незнакомы с понятием альтернативного потока данных, обратитесь к статье "How To Use NTFS Alternate Data Streams", http://support.microsoft.com/?kbid=105763.

Содержимое альтернативного потока данных для какого-либо файла можно просмотреть, введя в командной строке следующую команду:

More < file:Zone.Identifier

где file - имя соответствующего файла. Если имя файла содержит пробелы, то оно должно быть заключено в кавычки. Довольно странно то, что встроенная команда Type процессора командной строки CMD.EXE не поддерживает работу с альтернативными потоками данных, поэтому в данном случае приходится пользоваться командой More с применением символа перенаправления ввода (<). После успешного завершения команды More ее выходные данные будут указывать на одну из четырех возможных зон: ZoneId=1 (загрузка из локальной сети), ZoneId=2 (загрузка с разрешенного сайта), ZoneId=3 (загрузка из Internet), или ZoneId=4 (загрузка с подозрительного сайта).

Рассмотрим пример. Допустим, в каталоге C:Program Files имеется файл DownloadedProgram.exe. После двойного щелчка мышью по данному файлу в Проводнике Windows появилось окно предупреждения системы безопасности, показанное на Рис. 1. Причина этого заключается в том, что совместимое с Attachment Manager приложение (в данном случае это Проводник Windows), используя альтернативный поток данных, определило, что данный файл был загружен из небезопасной зоны, поэтому он не должен запускаться без уведомления об этом пользователя. Если теперь запустить указанным выше способом команду More применительно к файлу DownloadedProgram.exe, то можно удостовериться в том, что данный файл действительно был выгружен из зоны с ZoneId=3, т.е. из Internet.

Windows Script Host (WSH), как и Проводник Windows, при запуске внешних программ с помощью метода Run объекта WshShell также обращается к API компонента Attachment Manager. И если обнаруживается, что альтернативный поток данных Zone.Identifier исполняемого файла, вызываемого из сценария, указывает на то, что данный файл был выгружен из небезопасной зоны, появляется аналогичное окно предупреждения. При этом ход выполнения сценария прерывается до тех пор, пока в данном окне не будет нажата кнопка Run - крайне неприятная ситуация, особенно в тех случаях, когда сценарий должен выполняться без вмешательства пользователя. Избежать остановки сценария, обусловленной появлением подобного окна предупреждения, можно несколькими способами:

Используйте другие программные средства для загрузки необходимых утилит. Браузеры других производителей, например, Firefox от Mozilla Foundation, не используют API Attachment Manager при загрузке файлов. Соответственно, если загрузка файлов осуществляется с помощью подобного браузера, то альтернативные потоки данных при этом не создаются.

Разблокируйте файлы, которые вы запускаете из своих сценариев (т.е. отключите для них проверку зоны). Диалоговое окно предупреждения, возникающее при запуске конкретного файла, можно отключить. Для этого, при следующем появлении данного окна, следует снять в нем флажок Always ask before opening this file (Всегда спрашивать перед открытием данного файла), после чего нажать кнопку Run. При снятии указанного флажка Windows удаляет альтернативный поток данных Zone.Identifier, связанный с этим файлом. Можно поступить и другим способом: находясь в Проводнике Windows, щелкнуть правой кнопкой мыши на соответствующем файле, выбрать из контекстного меню пункт Properties (Свойства) и нажать клавишу Unblock (см. Рис. 2).

Удалите альтернативные потоки данных у запускаемых файлов, воспользовавшись утилитой Streams.exe от компании Sysinternals. Программа Streams.exe является свободно распространяемой утилитой командной строки компании Sysinternals (http://www.sysinternals.com), которая позволяет выявлять наличие альтернативных потоков данных и удалять их. Она также может работать с наборами файлов и просматривать содержимое подкаталогов. Например, с помощью приведенной ниже команды можно удалить альтернативные потоки данных для всех файлов с расширением *.exe, находящихся в каталоге C:Downloads, включая подкаталоги:

streams -s -d C:Downloads*.exe

Присвойте нужное значение переменной среды SEE_MASK_NOZONECHECKS. Как описано в документе "The Open File - Security Warning dialog box ...in Windows XP Service Pack 2", проверку зон можно отключить, присвоив переменной SEE_MASK_NOZONECHECKS значение 1. На Листинге 1 показано, как это можно реализовать через программу на VBScript. Однако следует иметь в виду, что Microsoft не рекомендует, чтобы переменная SEE_MASK_NOZONECHECKS все время имела значение 1, поскольку при этом полностью отключается механизм проверки зон.

Запускайте исполняемые файлы через Cmd.exe. Оболочка командной строки cmd.exe не использует Attachment Manager API, поэтому запуск исполняемых файлов через cmd.exe позволяет избежать появления рассматриваемых диалоговых окон предупреждения. Пример вызова программы через cmd.exe из сценария VBScript показан на Листинге 2. В данном фрагменте путь к cmd.exe определяется через переменную среды COMSPEC, а параметру intWindowStyle метода Run присваивается значение 0, что соответствует скрытому режиму выполнения процесса cmd.exe. При этом программа, запускаемая через cmd.exe будет выполняться в видимом режиме.

Если у Вас есть желание поэкспериментировать с альтернативными потоками данных, приводящими к рассмотренной в данной заметке ситуации, предлагаю воспользоваться приведенным на Листинге 3 сценарием командной строки AddAlternateDataStream.cmd, с помощью которого можно добавить альтернативный поток данных Zone.Identifier к выбранному файлу. Синтаксис запуска сценария выглядит так:

AddAlternateDataStream file

где file - имя файла, которому нужно назначить альтернативный поток данных. Процедура добавления к файлу альтернативного потока данных обозначена меткой A. В указанном сценарии используется значение ZoneId=3, что соответствует ситуации, когда файл загружается из зоны Internet. При проведении экспериментов с другими зонами данное значение может быть изменено требуемым образом.


Листинг 1. Пример использования переменной среды SEE_MASK_NOZONECHECKS
Dim WshShell, Command
Set WshShell = CreateObject("WScript.Shell")
Command = "C:Program FilesDownloadedProgram.exe"
WshShell.Environment("PROCESS")("SEE_MASK_NOZONECHECKS") = 1
WshShell.Run """" & Command & """"
WshShell.Environment("PROCESS").Remove("SEE_MASK_NOZONECHECKS")

Листинг 2. Пример запуска программы через Cmd.exe
Dim WshShell, Command
Set WshShell = CreateObject("WScript.Shell")
Command = "C:Program FilesDownloadedProgram.exe"
WshShell.Run WshShell.Environment("PROCESS")("COMSPEC") _
  & " /c """ & Command & """", 0

Листинг 3. Сценарий AddAlternateDataStream.cmd
@Echo Off
If {%1}=={} Goto :HELP
If {%1}=={/?} Goto :HELP
Goto :MAIN
:HELP
Echo Usage: AddAlternateDataStream ^
Echo.
Echo Adds XP SP2 Attachment Manager Internet zone information to the alternate
Echo data stream for ^.
Goto :EOF
:MAIN
SetLocal EnableExtensions
:: Начало фрагмента A
If Exist %1 (
  >  %1:Zone.Identifier Echo [ZoneTransfer]
  >> %1:Zone.Identifier Echo ZoneId=3
) Else (
  Echo File not found - %~1
)
:: Конец фрагмента A
EndLocal
Goto :EOF