Как вызвать метод службы Windows из VBScript? - PullRequest
4 голосов
/ 25 мая 2011

Допустим, я создал службу Windows, предоставив метод foo(param1 as string)

Можно ли каким-то образом напрямую вызывать foo("SomeAwesomeString") из VBScript (т. Е. Без необходимости запуска дополнительного процесса)?

Вариант использования таков: я пытаюсь написать приложение-расширение для hMailServer (hMS) , но hMS может вызывать сценарии VBscript только тогда, когда произошло событие. Я могу заставить VBscript запускать .exe каждый раз, когда происходит событие, но обработка включает в себя открытие и закрытие соединения с внутренней базой данных. Таким образом, каждый вызов очень дорогой. Я думал, что смогу сократить расходы, имея Службу для поддержания соединения (то есть, открывая его один раз и открывая заново, если соединение закрыто). Кроме того, реализация обработки в качестве фоновых рабочих потоков приведет к неблокирующей обработке + меньше затрат на запуск процесса.


Обновление: как я это сделал

Уф. После лотов поиска и экспериментов, я думаю, что нашел способ. Я выложу это как ответ ниже. Если кто-то может дать лучший ответ, чем мой, не стесняйтесь писать. Если это действительно лучше, я сниму галочку с моего ответа и отмечу ваш.


Незначительное обновление / ошибка:

Я забыл сказать, что служба Windows создана с использованием VB.Net 2010. Извините.


Окончательное обновление: я сдаюсь

После поиска по всему Интернету - и экспериментов без конца - я сдаюсь.

Я решил не выставить метод, но использовать взамен Named Pipes . Теперь сценарию VBScript просто нужно записать в FSO, открытый для //./pipe/PIPENAME, и позволить службе выяснить, какого чёрта хочет VBScript.

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

Ответы [ 4 ]

1 голос
/ 26 мая 2011

Вы можете объединить два подхода.

Реализуйте свой сервис, как вы предлагаете, для поддержки необходимых соединений.

Затем вы из VBScript вызываете крошечный .exe, целиком которого являетсяпередать свой параметр командной строки вышеупомянутой службе.

На самом деле, вместо того, чтобы создавать разные .exe для каждого API (например, "hms-foo.exe", "hms-bar.exe"или что-то еще), сделайте имя API просто еще одним параметром командной строки.

Теперь у вас может быть один очень простой .exe файл, например, hmscom.exe, который VBScript может вызывать с помощью командной строки, например:"hmscom.exe foo SomeAweSomString".Внутренне hmscom.exe будет делать все необходимое для вызова экспортированного API, foo () с параметром «SomeAweSomString».

Еще лучше было бы реализовать вышеуказанную функциональность в DLL вместо .exe ииспользуйте стандартный файл rundll32.exe для вызова точки входа в DLL с аргументами командной строки в качестве параметров, после чего указанная функция обменивается данными со службой, как описано выше для .exe.

Это усложнит задачупользователь случайно вызвал вашу службу, случайно дважды щелкнув по файлу .exe, поскольку его не будет.

0 голосов
/ 18 февраля 2019

Вот как я сделал точно такую ​​же вещь , которую вы пытались сделать - да, приложение-помощник для hMailServer для проверки получателей электронной почты и отклонения почты, если какие-либо получатели не разрешены. У меня был vbscript, который делал то же самое, но примерно 1% писем не было доставлено, потому что vbscript выдает сообщение «DSN not found» - DSN - это ссылка на базу данных, которая имеет правила. Поскольку я не мог это исправить, я подумал о вспомогательном приложении, которое будет вызываться из события OnAcceptMessage hmail. Я передал бы идентификатор отправителя и получателей в мое приложение, и я получил бы хорошо или не хорошо сообщение с объяснением.

То, как я это сделал, - это создать приложение сервера TCP, которое прослушивает заранее определенный порт. Объект winsock создается для связи с сервером в VBScript, который передает отправителю / получателю. Поскольку сервер является постоянным, повторного вызова exe-файла или открытия / закрытия соединений с БД не происходит.

Вот несколько хороших ресурсов для этого: http://www.vbforums.com/showthread.php?453366-How-to-send-a-simple-string-via-TCP

https://www.symantec.com/connect/downloads/protocolvbs-windows-vbscript-test-tcp-service-response

Надеюсь, я получу ответ от автора, ведь прошло всего 7 лет, 9 месяцев с момента опубликования вопроса:)

0 голосов
/ 26 мая 2011

Хорошо, вот как я это делаю:

  1. Отметьте классы, которые будут выставлены, с <ComClass(), ProgId("ServiceName")> атрибутами

  2. Установите флажок « Сделать сборку COM-Visible » в свойствах проекта> Приложение> Информация о сборке

  3. Сделать класс установщика службы

  4. 1020 * Опубликовать *

  5. Используйте InstallUtil.exe для развертывания. E.g.:

    C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe <appname>.exe.deploy
    
  6. Используйте regasm для публикации интерфейса COM. E.g.:

    C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\regasm <appname>.exe.deploy /codebase <progid>
    
  7. Готово!

Теперь я могу вызывать Сервис, используя интерфейс COM, например ::1010.

Dim objService
Set objService = CreateObject("ServiceName")

Dim rslt
rslt = objService.Foo("SomeAwesomeString")

Уф! Так много прыгать через обручи: - /


Обновление: сбой

После некоторого тестирования ... Я обнаружил, что экземпляр CreateObject-ed не совпадает с запущенной в данный момент службой sigh .

Я буду экспериментировать больше.

0 голосов
/ 26 мая 2011

Да, проверьте WCF Это невозможно для связи между двумя программами.

...