公開日:12/5/2021  更新日:12/6/2021

  • twitter
  • facebook
  • line

常駐プログラム (Python) をWindowsにサービス登録

やりたいこと

現在、powershellのコンソール実行でpythonの常駐プログラムを実行している。
コンソール実行だと、ログインセッションが切れるとプログラムが終了してしまう。
なので、プログラムをWindowsにサービス登録してバックグラウンド実行したい。
調べたところ、pywin32 を使用することで簡単に実装することが出来た。

サービス登録

事前準備

システム環境変数に以下のパスを追加した。
各々のインストールしたpythonのバージョンに合わせて設定する。

C:\Users\atsus\AppData\Local\Programs\Python\Python38
C:\Users\atsus\AppData\Local\Programs\Python\Python38\Scripts
C:\Users\atsus\AppData\Local\Programs\Python\Python38\Lib\site-packages\pywin32_system32
C:\Users\atsus\AppData\Local\Programs\Python\Python38\Lib\site-packages\win32

システム環境変数のpathが設定されていない場合、サービス実行する際に下記エラーが発生する。

サービスエラー

ソースコード

1分おきに、実行中のメッセージをログに出力する常駐プログラム
service.py

import win32service
import win32serviceutil
import win32event
import logging
import servicemanager
import socket
import time

logging.basicConfig(
    filename = 'C:\\Users\\atsus\\desktop\\PythonService\\{}-app.log'.format(datetime.utcnow().strftime("%Y%m%d")),
    level = logging.DEBUG,
    format="%(asctime)s:LINE[%(lineno)s] %(levelname)s %(message)s"
)

class PythonService(win32serviceutil.ServiceFramework):
	_svc_name_ = "PythonService"
	_svc_display_name_ = "Python Service"
	_svc_description_='sample test'
	
	def __init__(self,args):
		win32serviceutil.ServiceFramework.__init__(self,args)
		self.stop_event = win32event.CreateEvent(None,0,0,None)
		socket.setdefaulttimeout(60)
		self.stop_requested = False

	def SvcStop(self):
		logging.info('サービスの停止を実行')
		self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
		win32event.SetEvent(self.stop_event)
		self.stop_requested = True

	def SvcDoRun(self):
		servicemanager.LogMsg(
			servicemanager.EVENTLOG_INFORMATION_TYPE,
			servicemanager.PYS_SERVICE_STARTED,
			(self._svc_name_,'')
			)
		self.main_loop()

	def main_loop(self):
		logging.info('サービス開始')
		while True:
			if self.stop_requested:
				logging.info('サービスを停止します')
				break
			try:
				time.sleep(60)
				logging.debug('実行中')

			except Exception as e:
				logging.error("Error occured.")
				logging.error(e)
		logging.info("サービス停止")
		return

if __name__=='__main__':
	win32serviceutil.HandleCommandLine(PythonService)

使用頻度の高いコマンド

管理者権限でコマンドプロンプトを実行する。
1.サービス登録

python service.py install

2.サービス開始

python service.py start

3.サービス停止

python service.py stop

4.サービス削除

python service.py remove

うまくいかない場合

サービス実行した際に、下記のようなエラーが出ることがある。

ローカルコンピューター上のPython Service サービスは起動して停止しました。サービスの中には、ほかのサービスやプログラムで使用されていない場合は自動的に停止するものがあります。

サービスエラー
その場合は、下記コマンドで詳しいエラー内容を確認する。

python service.py debug

出力結果

Debugging service PythonService - press Ctrl+C to stop.
Error 0xC0000003 - The instance's SvcRun() method failed

<Error getting traceback - traceback.print_exception() failed

(null): (null)

または、Windows のイベントビューアーを開いてエラー内容を確認する。
イベントビューアー

戻る