Отправить строковые команды или байты в службу Windows?(При запуске) - PullRequest
4 голосов
/ 06 января 2011

Есть ли способ передать команды в виде строки или байтового массива в службу Windows?(При работе)

Ответы [ 4 ]

7 голосов
/ 06 января 2011

Иногда я буду размещать службу WCF в службе Windows с целью управления поведением службы во время выполнения.

Если вы действительно просто хотите отправить необработанные данные в службу и не хотите заниматься настройкой службы WCF (что, между прочим, не так уж сложно сделать), вы, вероятно, можете сделать это, используя Именованные каналы или прослушиванием соединений через сокет на каком-либо порту.

7 голосов
/ 06 января 2011

Вам нужна какая-то форма IPC (межпроцессное взаимодействие). Какой из них вы выберете, может сильно зависеть от того, что вы хотите разрешить, а что нет. Например, вам нужно учитывать следующее:

  1. Должен ли какой-либо компьютер отправлять этот запрос в службу или только на локальный компьютер?
  2. Может ли какой-либо пользователь иметь возможность отправить этот запрос, или только определенные пользователи / роли?
  3. Если содержимое сообщения видят другие пользователи, это потенциальное нарушение безопасности?
  4. Нужно ли службе подтверждать сообщение или отправлять ответ?
  5. Должно ли сообщение быть защищенным от несанкционированного доступа?
  6. Сколько процессов / потоков будет отправлять сообщения в службу одновременно?

Как вы видите, есть только множество проблем, которые вы открываете, когда вводите IPC. Примите во внимание приведенные выше вопросы и найдите следующие возможные решения:

  1. .Net Remoting - Легко, но имеет проблемы с безопасностью и надежностью.
  2. Службы WCF - (.Net 3 или более поздняя версия). Легко кодируется, не очень надежен при больших нагрузках.
  3. Сокеты - трудно кодировать, трудно понять, но можно заставить работать.
  4. DCOM - размещение COM-объекта в вашем .Net-процессе и разрешение Windows маршализовать вызов.
  5. Win32 RPC - Необработанные библиотеки Win32 существуют в C # , или вы можете написать свою собственную.

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

Поскольку вы указали, что пытались вызвать службу с локального компьютера, самый простой способ - это использовать WCF поверх именованных каналов (который пытается ограничить связь с локальным компьютером). Если вы просто хотите передавать двоичные данные в службу и из службы, то библиотека RPC, связанная выше, будет работать нормально.

В следующем примере демонстрируется использование вышеуказанной библиотеки RPC:

Поставьте это на службу:

Guid iid = new Guid("{....}");
using (RpcServerApi server = new RpcServerApi(iid))
{
    server.OnExecute += 
    delegate(IRpcClientInfo client, byte[] arg)
    {
        byte[] response;
        //do whatever
        return response;
    };

    server.AddProtocol(RpcProtseq.ncalrpc, "MyServiceName", 5);
    server.AddAuthentication(RpcAuthentication.RPC_C_AUTHN_WINNT);
    server.StartListening();
    ...

А вот код клиента:

Guid iid = new Guid("{....}");
using (RpcClientApi client = new RpcClientApi(iid, RpcProtseq.ncalrpc, null, "MyServiceName"))
{
    client.AuthenticateAs(null, RpcClientApi.Self, RpcProtectionLevel.RPC_C_PROTECT_LEVEL_PKT_PRIVACY, RpcAuthentication.RPC_C_AUTHN_WINNT);
    byte[] input, output;
    output = client.Execute(input);
}
2 голосов
/ 06 января 2011

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

Вот пример программного запуска зарегистрированной службы с именем "myService"

using System.ServiceProcess;
//...
            System.ServiceProcess.ServiceController Service;
            Service = new ServiceController("myService");
            if (Service != null && Service.Status == ServiceControllerStatus.Stopped)
                    Service.Start();
//...

Посмотрите в SeviceController.Вы, вероятно, ищете:

    //
    // Summary:
    //     Executes a custom command on the service.
    //
    public void ExecuteCommand(int command);

Я понимаю, что эти команды должны быть предопределены.Вы не можете передавать произвольные команды сервисам, т. Е. Это не метод передачи данных.

1 голос
/ 06 января 2011

Как упоминалось @Derrick, можно использовать .Start(), который также может принимать аргументы, которые могут быть переданы службе (но это во время выполнения, а не во время выполнения).

Если вы хотите передать информацию во время работы службы, у вас есть несколько вариантов:

  1. Создать прослушиватель службы и использовать конечные точки для связи (WCF, Именованные каналы и т. Д.)
  2. Используйте встроенные окна OnCustomCommand , но тогда вы ограничены целым числом.
  3. Windows имеет некоторую информацию о динамической настройке службы Windows , но выглядит как изменение файла конфигурации и использование преимущества OnConfigurationChange (если это опция)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...