Как передать параметр в службу Windows раз и навсегда при установке вместо каждого запуска

У нас есть приложение-служба Windows, которое может принимать параметры командной строки, такие как:

MyService -option 

Пока что, когда мы хотим запустить службу с параметром, мы делаем это либо вручную из диалогового окна "Свойства службы" (в поле "Параметры запуска"), либо с помощью команды

sc start MyService -option  

Нам нужен способ установить службу "навсегда" с этим параметром, чтобы пользователям просто нужно было запускать / останавливать ее без необходимости каждый раз устанавливать параметр.

Кстати, добавление параметра в запись реестра ImagePath не работает, как и установка следующим образом:

MyService -option /install

Обновлено: Спасибо за ответы, которые помогают мне уточнить вопрос.
Чего я хотел бы добиться, так это установить параметр на уровне самого сервиса (например, со свойствами) на случай, если в одном исполняемом файле более 1 сервиса. Параметр конфигурации binpath просто обновляет запись ImagePath в реестре. Это не может быть конкретной услугой.

10 ответов

sc config MyService binPath= MyService.exe -option

Обновить

Отдельные параметры сервиса хранятся в реестре по ключу HKLM\SYSTEM\CurrentControlSet\Services\<serviceName>\Parameters, Я не уверен, хотя, как параметры передаются в сервис. Я считаю, что СКМ читает эти значения тогда, когда он вызывает StartService он передает их ServiceMain Перезвоните.

Как насчет помещения параметра в файл конфигурации?

Единственное, что мне помогло, - это добавить параметр в ImagePath в реестре, как показано ниже: https://s tackru.com/images/dd602f61f14566bdb95aaceda7f2a777da96150b.png

Согласно документации ServiceBase.OnStart:

Аргументы, введенные в консоли, не сохраняются; они передаются службе единовременно при запуске службы с панели управления. Аргументы, которые должны присутствовать при автоматическом запуске службы, могут быть помещены в строковое значение ImagePath для раздела реестра службы (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\). Вы можете получить аргументы из реестра, используя метод GetCommandLineArgs, например: string[] imagePathArgs = Environment.GetCommandLineArgs();.

Аргументы, передаваемые в командной строке через ImagePath, доступны в main() или через GetCommandLine(). Вы можете установить с аргументами командной строки, а затем в ServiceMain проверить, были ли переданы какие-либо аргументы в параметре lpszArgs. Если нет, вызовите GetCommandLine и посмотрите, были ли таковые переданы таким образом.

Powershell может сделать это, но для этого нужно использовать.Net.

new-Object System.ServiceProcess.ServiceController("$ServiceName",$ComputerName)).Start("$Parameter")

Если существует несколько служб с одним и тем же исполняемым файлом, вы должны устанавливать их с разными именами служб. Вы можете ссылаться на имя сервиса вместо параметров.

Чтобы получить имя службы, вы можете использовать это. Как служба Windows может определить свое имя службы?

Если вы хотите передавать параметры при автоматическом запуске службы, это может помочь: /questions/37840/pri-sozdanii-servisa-s-scexe-kak-peredat-parametryi-konteksta/37852#37852

Хорошей иллюстрацией будет посмотреть, как работает Mysql:

      >sc qc MySql80
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: MySql80
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : "C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqld.exe" --defaults-file="C:\ProgramData\MySQL\MySQL Server 8.0\my.ini" MySQL80
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : MySQL80
        DEPENDENCIES       :

затем вы можете установить или обновить свой сервис:

sc config XXXXService binPath="\"C:\License Manager\Bin\LicenseService.exe\" 9002"

Обратите внимание на экранированные кавычки, чтобы защитить .exe от перехвата пути. также в вашей реализации значение, переданное таким образом, не передается в OnStart(string[] args);

Ваша целевая служба должна добавить специальный код для получения значения командной строки. в том же контексте сложных вещей в службе Windows: помните, что текущий каталог — это System32, который вы можете обойти, найдя базовый каталог текущего домена приложения или даже передав нужный каталог также в командной строке на этапе установки.

Используйте команду SC (service control), она дает вам гораздо больше возможностей, чем просто запуск и остановка.

DESCRIPTION:
          SC is a command line program used for communicating with the
          NT Service Controller and services.
  USAGE:
      sc <server> [command] [service name]  ...

      The option <server> has the form "\\ServerName"
      Further, help on commands can be obtained by typing: "sc [command]"
      Commands:
        query-----------Queries the status for a service, or
                        enumerates the status for types of services.
        queryex---------Queries the extended status for a service, or
                        enumerates the status for types of services.
        start-----------Starts a service.
        pause-----------Sends a PAUSE control request to a service.
        interrogate-----Sends an INTERROGATE control request to a service.
        continue--------Sends a CONTINUE control request to a service.
        stop------------Sends a STOP request to a service.
        config----------Changes the configuration of a service (persistent).
        description-----Changes the description of a service.
        failure---------Changes the actions taken by a service upon failure.
        qc--------------Queries the configuration information for a service.
        qdescription----Queries the description for a service.
        qfailure--------Queries the actions taken by a service upon failure.
        delete----------Deletes a service (from the registry).
        create----------Creates a service. (adds it to the registry).
        control---------Sends a control to a service.
        sdshow----------Displays a service's security descriptor.
        sdset-----------Sets a service's security descriptor.
        GetDisplayName--Gets the DisplayName for a service.
        GetKeyName------Gets the ServiceKeyName for a service.
        EnumDepend------Enumerates Service Dependencies.

      The following commands don't require a service name:
      sc <server> <command> <option>
        boot------------(ok | bad) Indicates whether the last boot should
                        be saved as the last-known-good boot configuration
        Lock------------Locks the Service Database
        QueryLock-------Queries the LockStatus for the SCManager Database
  EXAMPLE:
          sc start MyService
Другие вопросы по тегам