DICOM listener Windows Service

116 views
Skip to first unread message

Michael Bowers

unread,
Apr 21, 2017, 8:39:37 PM4/21/17
to pynetdicom

I'm trying to create a Windows Service that implements a DICOM listener with pynetdicom.  I can create a simple program built around the AE class and run it successfully, and I can create a Windows service successfully, but I can't combine them.

I've attached the attempt, and copied it below in text.

For proof of concept, I just want to field a CEcho. The AE sees the echo request, and creates an association, but never calls the OnReceiveEcho function.  It also never sees another echo, so assuming it locks up.  The port is locked up as well.

Any help would be enormously appreciated.

Thanks,

Mike B.


import win32service  
import win32serviceutil  
import win32event

import os
import sys

import subprocess
from netdicom import AE, StorageSOPClass, VerificationSOPClass

class PySvc(win32serviceutil.ServiceFramework, AE):
    
    LocalDicomAETitle = 'MyAE'
    LocalDicomPort = 2100

    _listenerSubproc = None
    _myAE = None
    # you can NET START/STOP the service by the following name  
    _svc_name_ = "DICOMCombinedListenerTestService"  
    # this text shows up as the service name in the Service  
    # Control Manager (SCM)  
    _svc_display_name_ = "DICOM Listener Service Test"  
    # this text shows up as the description in the SCM  
    _svc_description_ = "A DICOM Listener for entering plan data to the Staging db"  
      
    def __init__(self, args):  
        win32serviceutil.ServiceFramework.__init__(self,args)
        # create an event to listen for stop requests on  
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)  
      
    def MyOnReceiveEcho(self):
        print "Echo received"

    # core logic of the service     
    def SvcDoRun(self):

        # start AE
        print "starting AE ... "
        _myAE = AE(self.LocalDicomAETitle, self.LocalDicomPort, [StorageSOPClass, VerificationSOPClass], [StorageSOPClass, VerificationSOPClass])

        _myAE.OnReceiveEcho = self.MyOnReceiveEcho
        _myAE.start()

        rc = None
        # if the stop event hasn't been fired keep looping  
        while rc != win32event.WAIT_OBJECT_0:
            # block for 5 seconds and listen for a stop event  
            rc = win32event.WaitForSingleObject(self.hWaitStop, 10000)
            print 'waited'
            
        _myAE.Quit()
      
    # called when we're being shut down      
    def SvcStop(self):
        # kill the listener subprocess
        self._listenerSubproc.terminate()
        # tell the SCM we're shutting down  
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)  
        # fire the stop event  
        win32event.SetEvent(self.hWaitStop)  
          
if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(PySvc)
    


WindowsService.rtf

Michael Bowers

unread,
Apr 25, 2017, 9:45:15 AM4/25/17
to pynetdicom

Turned out to be pretty trivial - needed a handler for the Associate Request event.

Anyway - here's an AE implemented as a Windows Service:

import win32service  
import win32serviceutil  
import win32event

import os
import sys

from netdicom import AE, StorageSOPClass, VerificationSOPClass
        
def MyOnReceiveEcho():
    print "handle echo"

def MyOnAssociateRequest(association):
    print "association requested"

def MyOnAssociateResponse(association):
    print "Association response received"
    
def MyOnReceiveStore(SOPClass, DS):
    print "Received C-STORE"
    return SOPClass.Success

class PySvc(win32serviceutil.ServiceFramework, AE):
    
    LocalDicomAETitle = 'DICOMListenerAE'
    LocalDicomPort = 2100

    _myAE = None
    # you can NET START/STOP the service by the following name  
    _svc_name_ = "ListenerTestService"  
    # this text shows up as the service name in the Service  
    # Control Manager (SCM)  
    _svc_display_name_ = "DICOM Listener Service Test"  
    # this text shows up as the description in the SCM  
    _svc_description_ = "A Trivial DICOM Listener for testing"  
      
    def __init__(self, args):  
        win32serviceutil.ServiceFramework.__init__(self,args)
        # create an event to listen for stop requests on  
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)  
      
    # core logic of the service     
    def SvcDoRun(self):

        # start AE
        print "starting AE ... "
        _myAE = AE(self.LocalDicomAETitle, self.LocalDicomPort, [StorageSOPClass, VerificationSOPClass], [StorageSOPClass, VerificationSOPClass])

        _myAE.OnReceiveEcho = MyOnReceiveEcho
        _myAE.OnAssociateRequest = MyOnAssociateRequest
        _myAE.OnAssociateResponse = MyOnAssociateResponse
        _myAE.OnReceiveStore = MyOnReceiveStore
        _myAE.start()
#         
        rc = None
        # if the stop event hasn't been fired keep looping  
        while rc != win32event.WAIT_OBJECT_0:
            # block for 5 seconds and listen for a stop event  
            rc = win32event.WaitForSingleObject(self.hWaitStop, 1000)
            print 'waited'
            
        _myAE.Quit()
      
    # called when we're being shut down      
    def SvcStop(self):

Patrice Munger

unread,
Apr 25, 2017, 7:46:20 PM4/25/17
to pynet...@googlegroups.com
I don't normally work on windows and I was trying to setup a windows environment to test your code. Glad you found the problem! It will certainly be useful for other people.

--
You received this message because you are subscribed to the Google Groups "pynetdicom" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pynetdicom+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Patrice Munger
Reply all
Reply to author
Forward
0 new messages