Hello,
J'ai écris un petit service windows en python en utilisant la class SMWinservice de Davide Mastromatteo.
Ce service a besoin d'exécuter un script python. Python3 est bien installé sur ma machine, toutes les variables d'ENV bien définies (user et system). Pourtant, python n'est trouvé que dans le cas où le service run en debug où le PATH de python.exe explicitement donné dans le call du script:
fichier E:\tmp\SMWinservice.py (cf pièce jointe)
fichier E:\tmp\MonService.py (cf pièce jointe)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 import socket import win32serviceutil import servicemanager import win32event import win32service class SMWinservice(win32serviceutil.ServiceFramework): '''Base class to create winservice in Python''' _svc_name_ = 'pythonService' _svc_display_name_ = 'Python Service' _svc_description_ = 'Python Service Description' @classmethod def parse_command_line(cls): ''' ClassMethod to parse the command line ''' win32serviceutil.HandleCommandLine(cls) def __init__(self, args): ''' Constructor of the winservice ''' win32serviceutil.ServiceFramework.__init__(self, args) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) socket.setdefaulttimeout(60) def SvcStop(self): ''' Called when the service is asked to stop ''' self.stop() self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) def SvcDoRun(self): ''' Called when the service is asked to start ''' self.start() servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, '')) self.main() def start(self): ''' Override to add logic before the start eg. running condition ''' pass def stop(self): ''' Override to add logic before the stop eg. invalidating running condition ''' pass def main(self): ''' Main class to be ovverridden to add logic ''' pass # entry point of the module: copy and paste into the new module # ensuring you are calling the "parse_command_line" of the new created class if __name__ == '__main__': SMWinservice.parse_command_line()
fichier E:\tmp\MonSubProcess.py (cf pièce jointe)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 import time,os,sys,logging,subprocess,io from SMWinservice import SMWinservice FORMATMSG='[%(asctime)-20s] %(levelname)-8.8s %(message)s'; FORMATTIMESTAMP='%Y-%m-%d %H:%M:%S'; logging.basicConfig( filename = 'E:\\tmp\\MonService.log', level = logging.INFO, format = FORMATMSG, datefmt = FORMATTIMESTAMP ) class MonService(SMWinservice): _svc_name_ = "MonService" _svc_display_name_ = "Mon Service" _svc_description_ = "Lance un sous programme python" def start(self): self.isrunning = True; logging.info("Service start") def stop(self): self.isrunning = False; logging.info("Service stop") def main(self): while self.isrunning: cmd = "E:/tmp/MonSubProcess.py 2>&1" p = subprocess.Popen(cmd,shell=True,stdout = subprocess.PIPE); with io.TextIOWrapper(p.stdout, encoding="utf-8") as output: for line in output: logging.info(line); p.wait(); RC = p.returncode; logging.info("MonSubProcess RC = {0}".format(RC)); time.sleep(10) if __name__ == '__main__': MonService.parse_command_line()
Pour information, j'ai setté la variable PYLAUNCH_DEBUG=1 dans le system pour avoir les LOG du lancement de python.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 import sys,io def main(): print("Subprocess started !!") if __name__ == '__main__': main();
METHODE 1:
Dans une console ADMINISTRATOR je fais:
et dans E:\tmp\MonService.log j'ai la log suivante en boucle
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 E:\>python E:\tmp\MonService.py install Installing service MonService Service installed E:\>python E:\tmp\MonService.py debug Debugging service MonService - press Ctrl+C to stop. Info 0x40001002 - The MonService service has started.
METHODE 2:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 [2019-06-08 12:40:14 ] INFO Service start [2019-06-08 12:40:14 ] INFO launcher build: 32bit [2019-06-08 12:40:14 ] INFO launcher executable: Console [2019-06-08 12:40:14 ] INFO File 'C:\Users\XXX\AppData\Local\py.ini' non-existent [2019-06-08 12:40:14 ] INFO File 'C:\windows\py.ini' non-existent [2019-06-08 12:40:14 ] INFO Called with command line: "E:\tmp\MonSubProcess.py" [2019-06-08 12:40:14 ] INFO maybe_handle_shebang: read 101 bytes [2019-06-08 12:40:14 ] INFO maybe_handle_shebang: BOM not found, using UTF-8 [2019-06-08 12:40:14 ] INFO locating Pythons in 64bit registry [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: C:\Users\XXX\AppData\Local\Programs\Python\Python37\python.exe is a 64bit executable [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: C:\Users\XXX\AppData\Local\Programs\Python\Python37\PCbuild\win32\python.exe: The system cannot find the path specified. [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: C:\Users\XXX\AppData\Local\Programs\Python\Python37\PCbuild\amd64\python.exe: The system cannot find the path specified. [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: C:\Users\XXX\AppData\Local\Programs\Python\Python37\PCbuild\python.exe: The system cannot find the path specified. [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: unable to open PythonCore key in HKLM [2019-06-08 12:40:14 ] INFO locating Pythons in native registry [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: C:\Users\XXX\AppData\Local\Programs\Python\Python37\python.exe: already found [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: C:\Users\XXX\AppData\Local\Programs\Python\Python37\PCbuild\win32\python.exe: The system cannot find the path specified. [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: C:\Users\XXX\AppData\Local\Programs\Python\Python37\PCbuild\amd64\python.exe: The system cannot find the path specified. [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: C:\Users\XXX\AppData\Local\Programs\Python\Python37\PCbuild\python.exe: The system cannot find the path specified. [2019-06-08 12:40:14 ] INFO locate_pythons_for_key: unable to open PythonCore key in HKLM [2019-06-08 12:40:14 ] INFO found no configured value for 'python' [2019-06-08 12:40:14 ] INFO search for default Python found version 3.7 at 'C:\Users\XXX\AppData\Local\Programs\Python\Python37\python.exe' [2019-06-08 12:40:14 ] INFO run_child: about to run 'C:\Users\XXX\AppData\Local\Programs\Python\Python37\python.exe "E:\tmp\MonSubProcess.py" ' [2019-06-08 12:40:14 ] INFO Subprocess started !! [2019-06-08 12:40:14 ] INFO child process exit code: 0 [2019-06-08 12:40:14 ] INFO MonSubProcess RC = 0
Dans la même console ADMINISTRATOR si je restart le service
Cette fois le subprocess python ne se lance pas car python n'est pas trouvé et j'ai le message suivant:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 E:\>python E:\tmp\MonService.py debug Debugging service MonService - press Ctrl+C to stop. Info 0x40001002 - The MonService service has started. Stopping debug service. E:\>python E:\tmp\MonService.py start Starting service MonService
Can't find a default Python.
avec dans E:\tmp\MonService.log la log en boucle suivante
METHODE 3:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 [2019-06-08 12:49:06 ] INFO Service start [2019-06-08 12:49:06 ] INFO launcher build: 32bit [2019-06-08 12:49:06 ] INFO launcher executable: Console [2019-06-08 12:49:06 ] INFO File 'C:\windows\system32\config\systemprofile\AppData\Local\py.ini' non-existent [2019-06-08 12:49:06 ] INFO File 'C:\windows\py.ini' non-existent [2019-06-08 12:49:06 ] INFO Called with command line: "E:\tmp\MonSubProcess.py" [2019-06-08 12:49:06 ] INFO maybe_handle_shebang: read 101 bytes [2019-06-08 12:49:06 ] INFO maybe_handle_shebang: BOM not found, using UTF-8 [2019-06-08 12:49:06 ] INFO locating Pythons in 64bit registry [2019-06-08 12:49:06 ] INFO locate_pythons_for_key: unable to open PythonCore key in HKCU [2019-06-08 12:49:06 ] INFO locate_pythons_for_key: unable to open PythonCore key in HKLM [2019-06-08 12:49:06 ] INFO locating Pythons in native registry [2019-06-08 12:49:06 ] INFO locate_pythons_for_key: unable to open PythonCore key in HKCU [2019-06-08 12:49:06 ] INFO locate_pythons_for_key: unable to open PythonCore key in HKLM [2019-06-08 12:49:06 ] INFO found no configured value for 'python' [2019-06-08 12:49:06 ] INFO search for default Python found no interpreter [2019-06-08 12:49:06 ] INFO Can't find a default Python. [2019-06-08 12:49:06 ] INFO MonSubProcess RC = 103
Si dans E:\tmp\MonService.py je met en dur le PATH de python
Dans la même console ADMINISTRATOR si je restart le service
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 def main(self): while self.isrunning: cmd = "C:/Users/XXX/AppData/Local/Programs/Python/Python37/python.exe E:/tmp/MonSubProcess.py 2>&1" p = subprocess.Popen(cmd,shell=True,stdout = subprocess.PIPE);
Sans surprise cela fonctionne car je by-pass toute la partie recherhe de python (vu que je n'ai pas les traces liées à PYLAUNCH_DEBUG=1)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 E:\>python E:\tmp\MonService.py stop Stopping service MonService E:\>python E:\tmp\MonService.py start Starting service MonService
Mon soucis est que sur ces 3 méthodes, seules la METHODE 2 qui ne marche pas m'intéresse
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 [2019-06-08 13:02:40 ] INFO Service start [2019-06-08 13:02:40 ] INFO Subprocess started !! [2019-06-08 13:02:40 ] INFO MonSubProcess RC = 0
Est-ce qu'il y a un problème avec mon insatll de Python, où des variables qui me manqueraient?
D'avance merci pour votre aide.
Amicalement.
PS:je joins le zip avec les fichiers .py
Partager