FoxIs, находящийся в каталоге Visual FoxPro ...\Samples\Servers\Foxisapi\FoxIs, иллюстрирует создание out-of-process .exe или in-process .dll с функциональностью ISAPI, к которому можно обращаться из Visual FoxPro, как самостоятельной программы, из клиентов автоматизации и из Web браузера. Изменения, которые вы сделаете в его классах, могут улучшить сервер автоматизации, вне зависимости от того, откуда он запущен.

Для того, чтобы открыть проект образца FoxIs

  • Напечатайте приведенную ниже команжу в окне Command:

     CopyCode imageСкопировать код
    MODIFY PROJECT (HOME(2) + 'servers\foxisapi\foxis\foxis')

Запуск образца FoxIs

Вы можете запустить образец FoxIs четырьмя разными путями. Когда вы будете пробовать код, то в качестве неплохой идеи можете воспользоваться рекомендуемым порядком:

Запуск из Visual FoxPro

Для запуска образца FoxIs из Visual FoxPro, выполните последовательность приведенных ниже команд в окне Command.

 CopyCode imageСкопировать код
SET DEFAULT TO (HOME(2) + 'servers\foxisapi\foxis\')
SET CLASSLIB TO employee
ox = CREATEOBJECT('employee')
ox.show

Запуск в качестве независимого исполнимого приложения

Вы можете построить исполнимый файл из образца с помощью приведенной ниже строки кода:

 CopyCode imageСкопировать код
BUILD EXE foxis FROM foxis

Скомпилированный файл, FOXIS.EXE, представляет из себя программу для Windows, которая может быть добавлена в Windows Start menu, запущена из Windows Explorer и тому подобным образом.

Запуск в качестве сервера автоматизации

Если FoxIs будет скомпилирован в .exe или в .dll, он регистрируется как сервер автоматизации в реестре Windows. Вы можете создать объект, основанный на классе employee из любого OLE контроллера, например, Excel, Visual Basic и Visual FoxPro:

 CopyCode imageСкопировать код
ox = CREATEOBJECT('foxis.employee')
ox.SHOW

Запуск из Web браузера

Вы можете даже запустить образец FoxIs из Web браузера, который может быть на другой машине, такой как 286 под MS-DOS, Unixe, Macintosh или Personal Digital Assistant.

Системные требования для использования через Internet

Для запуска образца FoxIs из Web браузера у вас должны быть запущены:

  • Windows 98 или Windows 2000 или более поздний.

  • ISAPI-совместимый Web сервер, такой как Microsoft Personal Web Server для Windows 98 или Microsoft Internet Information Services (IIS). IIS идет в поставке с Windows 2000 и более поздними версиями и может быть загружен с сайта www.microsoft.com; Personal Web Server также может быть загружен с сайта www.microsoft.com.

Если вы используете Windows 2000 или более позднюю версию, вам необходимо запустить утилиту DCOMCNFG, для конфигурирования DCOM с тем, чтобы обеспечить права сервису IIS на создание OLE объектов.

Для конфигурирования Windows 2000 или поздних DCOM

  1. В окне Command операционной системы, не Visual FoxPro!!!, напечатайте DCOMCNFG м затем нажмите Enter.

  2. На закладке Applications выберите имя сервера автоматизации. Когда вы компилировали сервер, ему по умолчанию было присвоено имя "employee".

  3. На закладке Default Security диалогового блока Distributed COM Configuration Properties, выберите Edit Default для каждой области : Default Access Permissions, Default Launch Permissions и Default Configuration Permissions.

  4. В появившемся диалоговом блоке Registry Value Permissions для каждой области выберите Add.

  5. В боксе Add Names диалогового окна Add Users and Groups, впечатайте имя вашего WWW сервера и имя пользователя вашего входа (login user name).

    Вы можете увидеть имя сервера в окне Microsoft Internet Service Manager Properties window. Если имя вашей машины - MINE, приведенная ниже строка в боксе Add Names установит пользователя по умолчанию:

     CopyCode imageСкопировать код
    \MINE\IUSR_MINE

    Если имя вашей машины - MINE и вы вошли как HOMER, то следующая строка в боксе Add Names установит разрешения для вас при входе:

     CopyCode imageСкопировать код
    \MINE\HOMER

Установка образца FoxIs для доступа чере Internet

Для установки образца FoxIs, вам необходимо создать .exe или .dll из проекта FoxIs, и затем скопировать файл в ваш каталог Inetsvr\Scripts.

Для устоновки образца FoxIs

  1. Откройте проект FOXIS.

  2. Щелкните на кнопке Build и затем выберите Build COM DLL.

  3. Скопируйте Foxisapi.dll в папку Inetsrv\Scripts.

Предварительное тестирование

Вы можете потестировать образец приложения FoxIs на различных уровнях для того, чтобы увидеть, что все сконфигурировано корректно.

Для того, чтобы видеть, что код работает

  1. В меню Program выберите Do.

  2. Выберите Main.prg в каталоге Visual FoxPro Samples\Servers\Foxisapi.

  3. Выберите Do.

Для того, чтобы увидеть, что .EXE работает

  1. В командном окне Visual FoxPro выдайте приведенную ниже команду:

     CopyCode imageСкопировать код
    BUILD EXE Foxis.exe FROM foxis
  2. Произведите двойной щелчок на Foxis.exe в Windows Explorer.

Для того, чтобы увидеть, что сервер автоматизации FoxIs работает

  • Выполните следующие команды:

     CopyCode imageСкопировать код
    OX= CREATEOBJECT('FOXIS.EMPLOYEE')
    OX.Show    && See if it works as a ISAPI Automation server
    ?OX.Startup( )  && See if it returns html

Намного легче протестировать сервер автоматизации из контроллера автоматизации, такого как Visual FoxPro до создания его в FoxIs.

Установка HTML страницы

Для того, чтобы этот предмет запустился, вам нужна HTML страница, которая содержит ссылку на URL. Например, возьмите приведенный ниже код и поместите его в файл Wwwroot\default.htm file.

 CopyCode imageСкопировать код
<a HREF="/scripts/foxisapi.dll/FoxIS.employee.startup"> <i>VFP ISAPI AUTOMATION SERVER DEMO PAGE</i> </a> 

Затем используйте браузер, который может быть на этой же машине и подсоединитесь к YourMachineName. Например, если имя вашей машины "myMachine," тогда напечайтайте "myMachine" как URL, на который нужно придти. Это выдаст страницу Default.htm page на сервере с именем "myMachine"

Инициализируется CreateObject("foxis.employee") и на объекте будет вызван метод Startup, который вернет сгенерированную страницу HTML. Если сервер автоматизации еще не построен, тогда Foxisapi.dll вернет HTML страницу с характерным для WEB кодом ошибки.

Затем используйте ваш Web браузер для обращения к приведенному выше href. Если вы получите HTML страницу с ошибкой, на которой говорится "Foxisapi error", тогда вы будете знать, что DLL загружена и работает.

 CopyCode imageСкопировать код
 <FORM ACTION = "/scripts/foxisapi.dll/foxis.employee.cmd">
<INPUT NAME="Cmd" VALUE = "Reset">
<INPUT TYPE="submit" VALUE="Dos Command">
</FORM>

В действительности вы можете положить любую действительную команду MS-DOS и это будет выполнено на серверной машине. Если это команда "Reset" (по умолчанию), тогда это высвободит первую инстанцию ISAPI сервера автоматизации наравне с ним самим, таким образом полностью высвобождая сервер ISAPI.

Кроме того, вы можете оценить любое выражение Visual FoxPro. Однако, если выражение Visual FoxPro отображает модальный диалог, такой, какой к примеру производит функция MESSAGEBOX( ), сервер автоматизации зависнет в ожидании ответа, который не может быть предоставлен. Однако, для in-process .dll, модальный интерфейс обслуживается автоматически и сервер автоматизации не зависнет.

 CopyCode imageСкопировать код
<FORM ACTION = "/scripts/foxisapi.dll/foxis.employee.cmd?FOXCMD">
<INPUT NAME="Cmd">
<INPUT TYPE="submit" VALUE="Fox Expression">
like "today is "+ cdow(date()) or 45 * 3 or SYS(2004)
</FORM>

Отладка сервера

Сервер Windows NT не имеет Desktop, поэтому на серверной машине не покажется интерфейс пользователя. Это означает, что вы должны отладить ваш сервер автоматиции до его развертывания.

Для трассироваки через Foxisapi.dll с помощью Visual C++ 5.0

  1. Откройте Foxisapi.mak.

  2. Удалите значок комментария из приведенной ниже строки кода в HttpExtensionProc:

     CopyCode imageСкопировать код
    //   _asm int 3
  3. Перестройте проект.

  4. Запустите MSDEV с идентификаторов процесса (PID) Inetinfo.exe. Вы можете получить идентификатор процесса в Windows Task Manager.

Этот процесс применяется к Windows 2000 или более поздней версии.

ЗамечаниеСовет

При отладке у вас не будет возможности выключить Web сервер для изменения сервера автоматизации. Вы можете просто прервать out-of-process компонент посылкой значения reset методу cmd, так как это описано выше, или, при использовании Win32 SDK с помощью TLIST, KILL, PVIEW или через Task Manager в Windows 2000 или более поздней версии.

Класс ISForm

"Движок" oобразца представляет собой класс ISForm в Isapi.vcx.

Точки входа в классе ISForm

Приведенные ниже методы могут быть вызваны из Web браузера с помощью Foxisapi.dll, для возврата HTML страниц.

Метод возвращает

Cmd

вычисление выражения Visual FoxPro или результаты команд MS-DOS.

DoSave

сохраняет изменения, сделанные пользователем в данных и возвращает HTML страницу employee.

Skipit

информацию работника для указанного работника в таблице. Skipit берет информацию cookie посылаемую в качестве параметра из Web браузера, проверяет таблицу cookies с целью поиска предыдущего номера записи и смещает указатель записи вперед или назад относительно номера записи, хранимого в таблице cookies. Новый номер записи записывается в таблицу cookies и вызывается метод GenHTML.

Startup

информацию работника в первой записи таблицы. Startup создает новый идентификатор cookie - id - для пользователя и посылает его назад как скрытый вход в HTML .

Поддержание сервера активным

Обычно, по каждому запросу от Web клиента, создается экземпляр сервер автоматизации, генерирующий HTML страницу и затем высвобождается с вызовом Release( ) в CallObject( ) в Foxisapi.cpp. Это означает, что полный Visual FoxPro runtime запускается и выгружается при каждом запросе.

Если сервер автоматизации ISAPI зарегистрирован, как Multi-Use и не вызывается Release(), тогда первый запрос запустит сервер, но последующие запросы будут использовать тот же самый экземпляр сервера, намного улучшая производительность. Код в Foxisapi.dll и методах Load, Cmd, DoSave, Startup и Skipit объекта ISForm управляет поддержкой одного активного экземпляра сервера.

Переменные в DLL

Задекларированы две переменных: pdispObj и pdispDoRelease. Когда сервер изначально создан, pdispObj представляет собой дескриптор диспетчера OLE объекта. Переменная pdispDoRelease устанавливается в то же самое значение, что и pdispObj и посылается по ссылке в качестве параметра методу ISForm сервера, который запрашивается Web браузером. Код в Visual FoxPro ISForm сервере автоматизации может изменить значение pdispDoRelease.

ЗамечаниеСовет

Для получения более подробной информации об этом образце смотрите комментарии в коде в ISForm и Foxisapi.cpp.

Событие загрузки формы

Когда ISForm создан, код в событии Load создает две глобальные переменные, gpInstance и gpDisp. Когда сервер ISForm загружен первый раз, значение переменной gpInstance устанавливается в 1. Последующие экземпляры увеличивают значение этой переменной. Когда экземпляр высвобождается, значение переменной gpInstance уменьшается.

Методы точки входа

Когда через Foxisapi.dll вызывается метод (Cmd, DoSave, Skipit, or Startup) ISForm , .dll передает методу указатель диспетчера по ссылке в в качестве параметра.

Когда сервер запускается первый раз, счетчик экземпляров устанавливается в 1 и указатель диспетчера сохраняется в глобальной переменной. Затем в указателе сохраняется значение 0.

 CopyCode imageСкопировать код
IF m.gnInstance = 1 
   IF TYPE('pDisp') $ 'NI' 
      gpDisp = m.pDisp
      pDisp = 0
   ENDIF
ENDIF

В этой точке, две переменные указывают на одно и тоже значение указателя диспетчера: gpDisp в ISForm сервера автоматизации и pdispObj в Foxisapi.dll. Значение pdispDoRelease в .dll равно 0, как оно и было изменено в ISForm сервера автоматизации.

Следующие друг за другом вызовы сервера увеличивают счетчик экземлпяров, новый pdispObj генерируется в .dll, сохраняется в pdispDoRelease, и направляется по ссылке в запрашиваемый метод. Так как значение gnInstance не равно 1, значение переменной gpDisp не изменяется. Начиная с этой точки, gpDisp в сервере автоматизации хранит отличающееся значение от pdispObj и pdispDoRelease в .dll.

Высвобождение сервера

Для принужления высвобождения, pdispDoRelease не может содержать 0 и должно иметь значение, отличающееся от значения pdispObject. На высвобождение сервера оказывает влияние значение, посылаемое приведенным ниже текстом HTML страницы:

 CopyCode imageСкопировать код
 <FORM ACTION = "/scripts/foxisapi.dll/foxis.employee.cmd">
<INPUT NAME="Cmd" VALUE = "Reset">
<INPUT TYPE="submit" VALUE="Dos Command">
</FORM>

Приведенный ниже код в методе cmd устанавливает значение pdispDoRelease для значения диспетчера первого экземпляра.

 CopyCode imageСкопировать код
CASE 'RESET'$upper(m.p1)
   m.pDisp= m.gpDisp

Код в .dll будет теперь высвобождать текущий экземпляр и оригинальный экземпляры, который поддерживался в наличии для предотвращения загрузки Visual FoxPro каждый раз при вызыве сервера.

Посылка HTML клиенту

Метод GenHTML класса ISForm вызывается из каждого метода точки входа. HTML, возвращенный из методаGenHTML, возвращается Web браузеру через Internet Information Services.

Если параметр режима, посылаемый методу GenHTML не равен "FORM," то метод GenHTML просто ищет значение в таблице и посылает назад преформатированный HTML.

 CopyCode imageСкопировать код
IF m.mode != 'FORM'
   =SEEK(m.mode,'html')
   rv = html.html
  RETURN m.rv
ENDIF

Если параметр режима равен "FORM," код в GenHTML идентифицирует каждую метку и текстбокс на форме, сортирует их в порядке сверху вних и слева-направо, вычисляет Captions и ControlSources элементов управления и использует возможности Visual FoxPro сливать текст для конструирования подходящего текста HTML для отображения на форме.

Если вы добавили в форму дополнительные метки и текстбоксы, то они автоматически отображаются в сгенерированном HTML.

Создание и использование Cookies

В качестве Web сервера, это приложение может быть запрощено многократно разными клиентами и нам необходимо сохранять трэки состояний пользователей. В этом случае, мы сохраняем трек текущего номера записи для такого пользователя. Мы могли бы предоставить пользователю экран логина и использовать имя пользователя, как ключ для cookie, но вместо этого, мы генерируем значение cookie в методе MakeCookie и посылаем его в качестве скрытого значения в HTML, посылаемом назад пользователю. Каждый раз, когда пользователь выбирает другую запись, мы читаем значение cookie из строки HTTP, посылаемой .dll, ищем cookie в таблице Cookies, находим текущий номер записи и перемещаем указатель относительно этого номера.

В процессе управления cookie используются свойства и методы, перечисленные ниже:

  • Свойство Cookie

  • Метод GetCookie

  • Метод MakeCookie

  • Метод WriteCookieInfo

Обработка ошибок

Если произошла ошибка, код в событии Error класса ISForm вызывает метод GenHTML с параметром "ERROR." GenHTML читает предформатированный HTML текст для ошибок и возвращает его коду события Error. Код события Error замещает информацию об ошибке для соответствующих мест в HTML:

 CopyCode imageСкопировать код
   LOCAL rv
   rv = THIS.GenHTML('ERROR')
   rv = strtran(m.rv,'%METHOD%',m.cMethod)
   rv = strtran(m.rv,'%ERRORNO%',STR(m.nError,4))
   rv = strtran(m.rv,'%ERRORMSG%',Message(1))
   rv = strtran(m.rv,'%LINENO%',STR(m.nLine,4))
   THIS.ErrorHTML = m.rv

Когда ErrorHTML что-то содержит, GenHTML посылает значение ErrorHTML назад, клиенту.

Таблицы, используемые в образце FoxIs

В дополнение к таблице employee, используемой для ввода данных и отображаения, образец FoxIs использует перечисленные ниже таблицы.

Таблица Описание

HTML

Хранит HTML текст посылаемый назад Web браузеру, как заголовок для вычислений FoxCMD и DosCMD илил в случае ошибки.

Cookies

Хранить трэки номеров записей для различных Web браузеров. Уникальное значение поля cookie посылается как скрытое значение в HTML тексте, посылаемое конкретному пользователю.

Смотрите также