Reputation: 193
I am working on using the Windows API to build a service. I have already tested and used the win32serviceutil.ServiceFramework module yet I am trying to get around using a 3rd party import.
I have the following so far:
LPSERVICE_MAIN_FUNCTIONW = ctypes.WINFUNCTYPE(ctypes.c_ulong, ctypes.c_wchar_p)
class SERVICE_TABLE_ENTRYW(ctypes.Structure):
_fields_ = [('ServiceName', ctypes.c_wchar_p),
('ServiceProc', LPSERVICE_MAIN_FUNCTIONW)]
def test():
logging.info('Test is running')
service_process = LPSERVICE_MAIN_FUNCTIONW(test)
service_table = SERVICE_TABLE_ENTRYW(ServiceName='Test_Service', ServiceProc=service_process)
ctypes.windll.advapi32.StartServiceCtrlDispatcherW(service_table)
However when calling StartServiceCtrlDispatcherW I get the following error back:
ValueError: Procedure probably called with too many arguments
If anyone could provide some assistance or direction it would be greatly appreciated
Upvotes: 1
Views: 271
Reputation: 177901
The LPSERVICE_MAIN_FUNCTIONW
callback is defined as:
typedef VOID (WINAPI *LPSERVICE_MAIN_FUNCTIONW)(
DWORD dwNumServicesArgs,
LPWSTR *lpServiceArgVectors
);
Which is:
LPSERVICE_MAIN_FUNCTIONW = ctypes.WINFUNCTYPE(None, ctypes.c_ulong, ctypes.POINTER(ctypes.c_wchar_p))
or if using ctypes.wintypes
:
from ctypes import WINFUNCTYPE,POINTER
from ctypes import wintypes as w
LPSERVICE_MAIN_FUNCTIONW = WINFUNCTYPE(None, w.DWORD, POINTER(w.LPWSTR))
Note the first parameter to WINFUNCTYPE
is the return type and the second parameter to the callback is a LPWSTR*
not a LPWSTR
.
Upvotes: 2