-
Notifications
You must be signed in to change notification settings - Fork 808
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ServiceFramework incompatible with venv #1450
Comments
The service is not run by your account, but by the System account, so it won't be aware of the virtual environment you were in when you installed the service. You need to manually add the packages from your venv to your environment before you try loading them. import sys, os, site
# Required for pythonservice.exe to find venv packages
# Will also load pywin32.pth, so the win32* packages will work as normal
script_dir = os.path.dirname(os.path.realpath(__file__))
site_packages = os.path.join(script_dir, ".pyenv", 'Lib', 'site-packages')
site.addsitedir(site_packages) |
I'm not sure what this means. Copy the venv to System's home directory? copy .\venv C:\windows\system32 Like that? |
I would strongly suggest you simply don't try and implement a service from inside a venv. If I take any action here it's likely to be to make it more obvious it doesn't work (ie, to fail even earlier, possibly even with a message to say you shouldn't be doing it) |
No, just add the code I included at the very start of your service and you should be fine. |
Oh I see. So the In the example, So then you could have all your service's modules in one place, but your |
The example program contains an error.
The hash-bang line should not reference the systems python. It ought to
reference the python interpreter in the virtual environment, and the Python
Launcher for Windows must be installed.
If those two things are done, then the service ought to operate correctly.
If it does not, then we need to make a fix. see
<https://docs.python.org/3/library/venv.html>
… scripts installed into virtual environments have a “shebang” line which
points to the virtual environment’s Python interpreter. This means that the
script will run with that interpreter regardless of the value of PATH. On
Windows, “shebang” line processing is supported if you have the Python
Launcher for Windows installed (this was added to Python in 3.3 - see *PEP
397* <https://www.python.org/dev/peps/pep-0397> for more details). Thus,
double-clicking an installed script in a Windows Explorer window should run
the script with the correct interpreter without there needing to be any
reference to its virtual environment in PATH.
On Wed, Dec 11, 2019 at 3:36 PM Tim Fisher ***@***.***> wrote:
Oh I see. So the site_packages folder (that contains the pywin32.pth file)
is what needs to be fed to site.addsitedir(), which adds it to the
environment (aka sys.path).
In your code ".pyenv" would be whatever you named your venv.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1450?email_source=notifications&email_token=AAEZOBKQ4JO6KFC7ZDBKKPDQYFTQBA5CNFSM4JZTNLSKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGU2A3A#issuecomment-564764780>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEZOBJQFFK3OGVKRCUQG2TQYFTQBANCNFSM4JZTNLSA>
.
|
Thanks! Yes I didn't notice this. You are correct. There ought to be an explicit path there that references the correct Python interpreter so in case the user doesn't have the venv activated, things should still work correctly. I recently converted from C# to Python so still trying to learn all the nuances. |
That's extremely interesting! There's no mention of relative paths, but setting the shebang to EDIT: I spoke too soon, package import still fails while running the service proper, both in debug and in service mode, so it doesn't seem to follow the same rules as the
So you're saying |
Sounds like you hit on the key, which is that It sounds like modifying how For me having venv support isn't so much about dependency isolation but about making deployment easier for end-users. Not only With venv the installation becomes: (1) Install Python, (2) copy these files and (3) run commands |
I did some research, and it would seem that the way Python venv dependencies usually work is by looking in the directory above As for picking and loading the correct python core DLL, the way .pyenv/pyvenv.cfg
EDIT: This section of the official doc goes through most of the process, including how to get debugging information out of |
I spent day with pythonservice code and found solution! import win32serviceutil
import win32service
import servicemanager
import sys
import os
import os.path
import multiprocessing
#
def main():
import time
time.sleep(600)
class ProcessService(win32serviceutil.ServiceFramework):
_svc_name_ = "SleepService"
_svc_display_name_ = "Sleep Service"
_svc_description_ = "Sleeps for 600"
_exe_name_ = sys.executable # python.exe from venv
_exe_args_ = '-u -E "' + os.path.abspath(__file__) + '"'
proc = None
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
if self.proc:
self.proc.terminate()
def SvcRun(self):
self.proc = multiprocessing.Process(target=main)
self.proc.start()
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.SvcDoRun()
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
def SvcDoRun(self):
self.proc.join()
def start():
if len(sys.argv)==1:
import win32traceutil
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(ProcessService)
servicemanager.StartServiceCtrlDispatcher()
elif '--fg' in sys.argv:
main()
else:
win32serviceutil.HandleCommandLine(ProcessService)
if __name__ == '__main__':
try:
start()
except (SystemExit, KeyboardInterrupt):
raise
except:
import traceback
traceback.print_exc() Modern python found its venv auto Service registred as "C:\Python\Python310\python310.exe" -u -E "C:\path\to\service.py" Worker in Process not blocking Framework and so start-stop works fast. |
@alex-eri When using pyinstaller and package the code to exe, it does not work. Can you fix it? Thanks |
Windows 10 build 1903, Python 3.8.0, pywin32 227, an activated venv and the following simple Windows service implementation:
If you pip install pywin32 into your venv and run pywin32_postinstall.py, then install and start the service will not work. The event log contains ModuleNotFoundError: No module named 'win32serviceutil' %2: %3
If you pip install pywin32 globally, it sees the pywin32 modules, but not any other package dependencies unless you also install those packages globally.
So, it really only works correctly if you install all packages globally and not use venv at all.
The text was updated successfully, but these errors were encountered: