Модули , используемые в данном примере , являются частью pywin32 (Python для расширений Windows). В зависимости от того, как вы установили Python, вам может потребоваться установить его отдельно.
import win32serviceutil import win32service import win32event import servicemanager import socket class AppServerSvc (win32serviceutil.ServiceFramework): _svc_name_ = «TestService» _svc_display_name_ = «Test Service» def __init__(self,args): win32serviceutil.ServiceFramework.__init__(self,args) self.hWaitStop = win32event.CreateEvent(None,0,0,None) socket.setdefaulttimeout(60) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) def SvcDoRun(self): servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_,»)) self.main() def main(self): pass if __name__ == ‘__main__’: win32serviceutil.HandleCommandLine(AppServerSvc)
Это просто шаблон. Код вашего приложения, вероятно, вызывающий отдельный скрипт, будет идти в функцию main ().
c# это просто — Windows Service за 5 минут
Вам также нужно будет установить это как сервис. Лучшее решение для этого в данный момент , как представляется, использовать Non-сосущий Service Manager.Это позволяет установить службу и предоставляет графический интерфейс для настройки командной строки, которую выполняет служба. Для Python вы можете сделать это, что создает сервис за один раз:
nssm install MyServiceName c:python27python.exe c:tempmyscript.py
Где my_script.py — это приведенный выше шаблон сценария, измененный для вызова сценария приложения или кода в функции main().Обратите внимание, что сервис не запускает скрипт Python напрямую, он запускает интерпретатор Python и передает ему основной скрипт в командной строке.
В качестве альтернативы вы можете использовать инструменты, предоставленные в Windows Server Resource Kit для вашей версии операционной системы, поэтому создайте службу.
Запуск веб-приложения Flask в качестве службы
Это вариант общего примера. Вам просто нужно импортировать приложение сценарий и вызвать это run() метод в сервисе main() функции. В этом случае мы также используем многопроцессорной модуль из — за проблемы с доступом WSGIRequestHandler .
import win32serviceutil import win32service import win32event import servicemanager from multiprocessing import Process from app import app class Service(win32serviceutil.ServiceFramework): _svc_name_ = «TestService» _svc_display_name_ = «Test Service» _svc_description_ = «Tests Python service framework by receiving and echoing messages over a named pipe» def __init__(self, *args): super().__init__(*args) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) self.process.terminate() self.ReportServiceStatus(win32service.SERVICE_STOPPED) def SvcDoRun(self): self.process = Process(target=self.main) self.process.start() self.process.run() def main(self): app.run() if __name__ == ‘__main__’: win32serviceutil.HandleCommandLine(Service)
Источник: www.codecamp.ru
Проблема со службой тем в Windows XP
Создаем службу (сервис) на C#
Приветствую всех сегодня рассмотрим тему касающуюся создание служб на C# под Windows.
Службы Microsoft Windows (NT-Services) – это процессы, выполняющиеся в фоновом режиме, не имеющие пользовательского интерфейса и работающие в отдельном сеансе. Службы могут запускаться автоматически при загрузке компьютера, даже если пользователь не вошел в систему.
Для мониторинга и управления службами Windows можно применять доступную в консоли ММС оснастку Services (Службы), которая находится в узле Computer Management (Управление компьютером).
Запустить Службу компонентов, можно выбрать Пуск>Средства администрирования>Служба компонентов
Перед вами запуститься консоль управлением службами установленными у вас системе:
Службу компонентов можно так же запустить другим способом, открыть консоль win+r и ввести services.msc
Создание службы:
Для этого запустите Visual Studio выберите Фаил>Создать проект>Служба Windows
В этом примере я покажу как программно создать службу без использования конструктора:
После запуска проекта, переходим в код программы, в моем случаи он выглядит так:
using System . Data ;
using System . Diagnostics ;
using System . Linq ;
using System . ServiceProcess ;
using System . Text ;
using System . Threading . Tasks ;
namespace __MyService__
public partial class Service1 : ServiceBase
public Service1 ( )
InitializeComponent ( ) ;
protected override void OnStart ( string [ ] args )
protected override void OnStop ( )
Обратите внимание, мы работаем в файле Service1.cs наследуемый от System.ServiceProcess.ServiceBase. а не в Program.cs
ServiceBase — базовый класс для службы, которая будет существовать в рамках служебного приложения. При создании нового класса службы, его необходимо унаследовать от класса ServiceBase.
Теперь зададим логику нашей программы, к примеру наша служба будет сохранять в фаил время запуска компьютера и время завершения работы.
using System ;
using System . ServiceProcess ;
namespace __MyService__
public partial class Service1 : ServiceBase
public Service1 ( )
InitializeComponent ( ) ;
CanShutdown = true ;
CanHandleSessionChangeEvent = true ;
protected override void OnStart ( string [ ] args ) < >
protected override void OnStop ( ) < >
protected override void OnSessionChange ( SessionChangeDescription changeDescription )
if ( changeDescription . Reason == SessionChangeReason . SessionLogoff )
file . WriteLine ( «Выключен: » + DateTime . Now . ToString ( ) ) ;
if ( changeDescription . Reason == SessionChangeReason . SessionLogon )
file . WriteLine ( «Включен: » + DateTime . Now . ToString ( ) ) ;
base . OnSessionChange ( changeDescription ) ;
Для этого мы переопределили метод который выполняется при получении события изменения от сеанса сервера терминалов. При возникновении события, происходит вызов метода, и проверка условий, включения или выключения компьютера.
Основной класс у нас готов, теперь нужно создать класс установщик. Так как п еред запуском службы Windows ее необходимо установить при этом служба будет зарегистрирована с помощью диспетчера управления службами. В проект можно добавить установщики, которые обрабатывают сведения о регистрации.
Для этого выберите наш проект и нажмите правую кнопку мыши, выберите добавить компонент, перед вами откроется окно в котором вам нужно выбрать Класс установщик, как показано ниже:
Настройки произвел в конструкторе студии таким образом:
Перейдем к коду этого класса, в нем я так же рассмотрел способ того как можно программно включить опцию :
Вход в систему: С системой учетной записью и установил программно галочку Разрешить взаимодействие с рабочим столом. Хотя судя из документации говориться что это сделать не возможно. Но я так понял что данная возможность была упразднена и в windows 10 от нее толку нет.
Раньше данная опция позволяла взаимодействовать с пользователем, делать скриншот экрана, и даже перехватывать нажатие клавиш.
Теперь посмотрим сам класс установщика:
Источник: www.nookery.ru
Создание службы Windows
В данной статье для примера демонстрируется создание службы, представляющей собой сервер цитат. В ответ на каждый запрос клиента сервер цитат должен возвращать случайную цитату из файла. В первой части решения используются три сборки — одна для клиента и две для сервера.
На рисунке ниже показан общий вид решения. Сборка QuoteServer содержит код, реализующий саму функциональность службы. Она отвечает за чтение файла цитат в кэше памяти и отправку ответов на запросы цитат с помощью сервера сокетов.
Сборка QuoteClient представляет собой многофункциональное клиентское приложение WPF. Это приложение отвечает за создание клиентского сокета для взаимодействия с QuoteServer. Третья сборка — QuoteService — представляет собой саму службу и отвечает за запуск и остановку QuoteServer, т.е. за управлением сервером QuoteServer.
Прежде чем создавать служебную часть этой программы, сначала понадобится создать простой сервер сокетов в дополнительной библиотеке классов на C#, которая будет использоваться из процесса службы.
Создание ключевой функциональности для службы
В службе Windows можно предусмотреть любую функциональность, такую как сканирование файлов для выполнения резервного копирования или проверка на предмет наличия вирусов или запуска сервера WCF. Однако все служебные программы обладают определенным сходством. В частности, все они должны предусматривать возможность запуска (и возврата управления вызывающему коду), останова и приостановки работы. В этом разделе показано, как реализовать такие возможности на примере сервера сокетов.
В Windows 7 в виде части компонентов может устанавливаться Simple TCP/IP Services. В состав этого компонента входит TCP/IP-сервер «quote of the day» (цитата дня), или qotd. Этот сервер представляет собой простую службу, которая прослушивает порт 17 и отвечает на каждый запрос случайным сообщением, которое берет из файла system32driversetcquotes. В нашем примере службы будет создаваться подобный сервер, но только в отличие от quotd, возвращающего строку в кодировке ASCII, этот сервер должен возвращать строку Unicode.
Сначала создадим библиотеку классов по имени QuoteServer и реализуем в ней код для сервера. Ниже по частям рассматривается код класса QuoteServer, который должен содержаться в файле QuoteServer.cs:
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace WinServices < public class QuoteServer < private TcpListener listener; private int port; private string filename; private Listquotes; private Random random; private Thread listenerThread; .
Конструктор QuoteServer() перегружен так, чтобы при вызове ему можно было передавать имя файла и номер порта. Конструктор, в котором передается только имя файла, по умолчанию предусматривает использование для сервера порта с номером 7890. В конструкторе по умолчанию имя файла по умолчанию выглядит как quotes.txt:
. public QuoteServer() : this(«quotes.txt») < >public QuoteServer(string filename) : this(filename, 7890) < >public QuoteServer(string filename, int port) < this.filename = filename; this.port = port; >.
Метод ReadQuotes() — это вспомогательный метод, который считывает все цитаты из файла, указанного в конструкторе. Затем все эти цитаты добавляются в коллекцию quotes типа List. Кроме того, создается экземпляр класса Random, который будет использоваться для возврата случайных цитат. Следующий вспомогательный метод — GetRandomQuoteOf TheDay(). Этот метод возвращает случайную цитату из коллекции quotes:
. protected void ReadQuotes() < quotes = File.ReadAllLines(filename).ToList(); random = new Random(); >protected string GetRandomQuoteOfTheDay() < int index = random.Next(0, quotes.Count); return quotes[index]; >.
В методе Start() весь файл с цитатами полностью считывается в коллекцию цитат типа List с использованием вспомогательного метода ReadQuaotes(). После этого запускается новый поток, который немедленно вызывает метод Listener().
Здесь используется поток, потому что метод Start() не может блокироваться и ожидать клиента; он должен немедленно возвращать управление вызвавшей его программе (диспетчеру SCM). Диспетчер SCM будет предполагать, что запуск не удался, если этот метод не будет возвращать ему управление в течение 30 секунд. Поток-слушатель конфигурируется как фоновый, чтобы приложение могло завершить свою работу без остановки этого потока. Свойству Name потока присваивается определенное значение для упрощения процесса отладки, поскольку тогда это значение будет появляться в отладчике.
. public void Start()
Функция потока ListenerThread() создает экземпляр TcpListener. Метод AcceptSocket() ожидает подключения клиента. Как только клиент подключается, AcceptSocket() возвращает информацию о сокете, который ассоциируется с этим клиентом. Далее вызывается метод GetRandomQuoteOfTheDay() для отправки клиенту выбираемой произвольным образом цитаты с помощью socket.Send():
. protected void ListenerThread() < try < IPAddress ipAddress = IPAddress.Parse(«127.0.0.1»); listener = new TcpListener(ipAddress, port); listener.Start(); while (true) < Socket clientSocket = listener.AcceptSocket(); string message = GetRandomQuoteOfTheDay(); UnicodeEncoding encoder = new UnicodeEncoding(); byte[] buffer = encoder.GetBytes(message); clientSocket.Send(buffer, buffer.Length, 0); clientSocket.Close(); >> catch (SocketException ex) < Trace.TraceError(String.Format(«QuoteServer «, ex.Message)); > > public void Stop() < listener.Stop(); >public void Suspend() < listener.Stop(); >public void Resume() < listener.Start(); >public void RefreshQuotes() < ReadQuotes(); >> >
Прежде чем переходить к построению службы на основе данного сервера, не помешает написать тестовую программу, которая просто создает экземпляр QuoteServer и вызывает его метод Start(). Это позволит протестировать функциональность сервера без необходимости иметь дело с деталями, касающимися конкретно службы. Тестовый сервер должен запускаться вручную, и его код можно легко просматривать в отладчике.
Чтобы получить такую тестовую программу, давайте создадим новое консольное приложение на C# и назовем его TestQuoteServer. Добавим в него ссылку на сборку класса QuoteServer и скопируем файл, содержащий цитаты, в каталог c:ProCSharpServices (иначе придется изменить аргумент конструктора, указав в нем место, куда был скопирован этот файл). После вызова конструктора экземпляра QuoteServer в этом приложении должен вызываться его метод Start(). После создания потока этот метод должен немедленно возвращать управление, чтобы консольное приложение продолжало выполняться до тех пор, пока не будет нажата клавиша :
static void Main()
Обратите внимание, что QuoteServer будет работать с портом 4567 локального хоста, на котором запускается данная программа, поэтому именно такие настройки потребуется далее указать в клиенте.
Пример QuoteClient
Клиент в рассматриваемом примере представляет собой простое приложение WPF, в котором пользователь может запрашивать цитаты из сервера. Это приложение использует класс TcpClient для подключения к работающему серверу, принимает возвращаемое сообщение и отображает его в текстовом поле. Его пользовательский интерфейс содержит только два элемента управления — Button и TextBox. У элемента Button есть событие Click, которое назначается методу OnGetQuote, а у ТехВох — свойство x:Name, которое устанавливается в textQuote.
Информация о сервере и портах, необходимая для подключения конфигурируется с помощью параметров приложения. Эти параметры доступны в окне свойств проекта на вкладке Settings (Параметры):
Здесь можно настраивать параметры ServerName (имя сервера) и PortNumber (номер порта), а также определять другие значения, подлежащие использованию по умолчанию. Если установить параметр Scope (область действия) в User (пользователь), то все производимые здесь настройки будут помещены в конфигурационный файл конкретного пользователя. Благодаря этому, для каждого пользователя приложения можно настроить собственные параметры. Вкладка Settings в Visual Studio предусматривает создание класса Settings, с помощью которого можно читать и записывать параметры. В код клиента потребуется добавить следующие директивы using:
using System; using System.Net.Sockets; using System.Text; using System.Windows; using System.Windows.Input;
Основная функциональность клиента находится в обработчике события щелчка на кнопке Get Quote (Получить цитату):
private void OnGetQuote(object sender, RoutedEventArgs e) < const int bufferSize = 1024; Cursor currentCursor = this.Cursor; this.Cursor = Cursors.Wait; string serverName = Properties.Settings.Default.ServerName; int port = Properties.Settings.Default.PortNumber; TcpClient client = new TcpClient(); NetworkStream stream = null; try < client.Connect(serverName, port); stream = client.GetStream(); byte[] buffer = new Byte[bufferSize]; int received = stream.Read(buffer, 0, bufferSize); if (received textQuote.Text = Encoding.Unicode.GetString(buffer).Trim(‘