Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
163
venv/Lib/site-packages/win32/Demos/service/pipeTestService.py
Normal file
163
venv/Lib/site-packages/win32/Demos/service/pipeTestService.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
# A Demo of services and named pipes.
|
||||
|
||||
# A multi-threaded service that simply echos back its input.
|
||||
|
||||
# * Install as a service using "pipeTestService.py install"
|
||||
# * Use Control Panel to change the user name of the service
|
||||
# to a real user name (ie, NOT the SystemAccount)
|
||||
# * Start the service.
|
||||
# * Run the "pipeTestServiceClient.py" program as the client pipe side.
|
||||
|
||||
import win32serviceutil, win32service
|
||||
import pywintypes, win32con, winerror
|
||||
# Use "import *" to keep this looking as much as a "normal" service
|
||||
# as possible. Real code shouldn't do this.
|
||||
from win32event import *
|
||||
from win32file import *
|
||||
from win32pipe import *
|
||||
from win32api import *
|
||||
from ntsecuritycon import *
|
||||
|
||||
# Old versions of the service framework would not let you import this
|
||||
# module at the top-level. Now you can, and can check 'Debugging()' and
|
||||
# 'RunningAsService()' to check your context.
|
||||
import servicemanager
|
||||
|
||||
import traceback
|
||||
import _thread
|
||||
|
||||
def ApplyIgnoreError(fn, args):
|
||||
try:
|
||||
return fn(*args)
|
||||
except error: # Ignore win32api errors.
|
||||
return None
|
||||
|
||||
class TestPipeService(win32serviceutil.ServiceFramework):
|
||||
_svc_name_ = "PyPipeTestService"
|
||||
_svc_display_name_ = "Python Pipe Test Service"
|
||||
_svc_description_ = "Tests Python service framework by receiving and echoing messages over a named pipe"
|
||||
|
||||
def __init__(self, args):
|
||||
win32serviceutil.ServiceFramework.__init__(self, args)
|
||||
self.hWaitStop = CreateEvent(None, 0, 0, None)
|
||||
self.overlapped = pywintypes.OVERLAPPED()
|
||||
self.overlapped.hEvent = CreateEvent(None,0,0,None)
|
||||
self.thread_handles = []
|
||||
|
||||
def CreatePipeSecurityObject(self):
|
||||
# Create a security object giving World read/write access,
|
||||
# but only "Owner" modify access.
|
||||
sa = pywintypes.SECURITY_ATTRIBUTES()
|
||||
sidEveryone = pywintypes.SID()
|
||||
sidEveryone.Initialize(SECURITY_WORLD_SID_AUTHORITY,1)
|
||||
sidEveryone.SetSubAuthority(0, SECURITY_WORLD_RID)
|
||||
sidCreator = pywintypes.SID()
|
||||
sidCreator.Initialize(SECURITY_CREATOR_SID_AUTHORITY,1)
|
||||
sidCreator.SetSubAuthority(0, SECURITY_CREATOR_OWNER_RID)
|
||||
|
||||
acl = pywintypes.ACL()
|
||||
acl.AddAccessAllowedAce(FILE_GENERIC_READ|FILE_GENERIC_WRITE, sidEveryone)
|
||||
acl.AddAccessAllowedAce(FILE_ALL_ACCESS, sidCreator)
|
||||
|
||||
sa.SetSecurityDescriptorDacl(1, acl, 0)
|
||||
return sa
|
||||
|
||||
# The functions executed in their own thread to process a client request.
|
||||
def DoProcessClient(self, pipeHandle, tid):
|
||||
try:
|
||||
try:
|
||||
# Create a loop, reading large data. If we knew the data stream was
|
||||
# was small, a simple ReadFile would do.
|
||||
d = ''.encode('ascii') # ensure bytes on py2k and py3k...
|
||||
hr = winerror.ERROR_MORE_DATA
|
||||
while hr==winerror.ERROR_MORE_DATA:
|
||||
hr, thisd = ReadFile(pipeHandle, 256)
|
||||
d = d + thisd
|
||||
print("Read", d)
|
||||
ok = 1
|
||||
except error:
|
||||
# Client disconnection - do nothing
|
||||
ok = 0
|
||||
|
||||
# A secure service would handle (and ignore!) errors writing to the
|
||||
# pipe, but for the sake of this demo we dont (if only to see what errors
|
||||
# we can get when our clients break at strange times :-)
|
||||
if ok:
|
||||
msg = ("%s (on thread %d) sent me %s" % (GetNamedPipeHandleState(pipeHandle)[4],tid, d)).encode('ascii')
|
||||
WriteFile(pipeHandle, msg)
|
||||
finally:
|
||||
ApplyIgnoreError( DisconnectNamedPipe, (pipeHandle,) )
|
||||
ApplyIgnoreError( CloseHandle, (pipeHandle,) )
|
||||
|
||||
def ProcessClient(self, pipeHandle):
|
||||
try:
|
||||
procHandle = GetCurrentProcess()
|
||||
th = DuplicateHandle(procHandle, GetCurrentThread(), procHandle, 0, 0, win32con.DUPLICATE_SAME_ACCESS)
|
||||
try:
|
||||
self.thread_handles.append(th)
|
||||
try:
|
||||
return self.DoProcessClient(pipeHandle, th)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
self.thread_handles.remove(th)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
def SvcStop(self):
|
||||
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
|
||||
SetEvent(self.hWaitStop)
|
||||
|
||||
def SvcDoRun(self):
|
||||
# Write an event log record - in debug mode we will also
|
||||
# see this message printed.
|
||||
servicemanager.LogMsg(
|
||||
servicemanager.EVENTLOG_INFORMATION_TYPE,
|
||||
servicemanager.PYS_SERVICE_STARTED,
|
||||
(self._svc_name_, '')
|
||||
)
|
||||
|
||||
num_connections = 0
|
||||
while 1:
|
||||
pipeHandle = CreateNamedPipe("\\\\.\\pipe\\PyPipeTest",
|
||||
PIPE_ACCESS_DUPLEX| FILE_FLAG_OVERLAPPED,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE,
|
||||
PIPE_UNLIMITED_INSTANCES, # max instances
|
||||
0, 0, 6000,
|
||||
self.CreatePipeSecurityObject())
|
||||
try:
|
||||
hr = ConnectNamedPipe(pipeHandle, self.overlapped)
|
||||
except error as details:
|
||||
print("Error connecting pipe!", details)
|
||||
CloseHandle(pipeHandle)
|
||||
break
|
||||
if hr==winerror.ERROR_PIPE_CONNECTED:
|
||||
# Client is already connected - signal event
|
||||
SetEvent(self.overlapped.hEvent)
|
||||
rc = WaitForMultipleObjects((self.hWaitStop, self.overlapped.hEvent), 0, INFINITE)
|
||||
if rc==WAIT_OBJECT_0:
|
||||
# Stop event
|
||||
break
|
||||
else:
|
||||
# Pipe event - spawn thread to deal with it.
|
||||
_thread.start_new_thread(self.ProcessClient, (pipeHandle,))
|
||||
num_connections = num_connections + 1
|
||||
|
||||
# Sleep to ensure that any new threads are in the list, and then
|
||||
# wait for all current threads to finish.
|
||||
# What is a better way?
|
||||
Sleep(500)
|
||||
while self.thread_handles:
|
||||
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)
|
||||
print("Waiting for %d threads to finish..." % (len(self.thread_handles)))
|
||||
WaitForMultipleObjects(self.thread_handles, 1, 3000)
|
||||
# Write another event log record.
|
||||
servicemanager.LogMsg(
|
||||
servicemanager.EVENTLOG_INFORMATION_TYPE,
|
||||
servicemanager.PYS_SERVICE_STOPPED,
|
||||
(self._svc_name_, " after processing %d connections" % (num_connections,))
|
||||
)
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
win32serviceutil.HandleCommandLine(TestPipeService)
|
Loading…
Add table
Add a link
Reference in a new issue