>*CallWindowsService.prg >LPARAMETERS tcService,tcAction >#DEFINE SERVICE_WIN32 0x30 >#DEFINE SERVICE_RUNNING 4 >_vfp.aUTOYIELD=.t. >SET ESCAPE ON >ON ESCAPE >SET PROCEDURE TO WINDOWSSERVICECLASS.PRG additive > >LOCAL ws As winservices, srv As winservice > >STORE 1 TO tnAnimate >STORE "" TO lcCurrentStatus, lcStatus > >DO WHILE m.lcCurrentStatus = m.lcStatus > > ws = CREATEOBJECT("winservices", Null, Null, SERVICE_WIN32) > srv = ws.GetService(m.tcService) > IF ISNULL(srv) > ? m.tcService + " service is not found on this computer" > EXIT > ENDIF > > if m.tnAnimate=1 > m.tnAnimate=2 > m.tcAnimate="|" > else > m.tnAnimate=1 > m.tcAnimate="-" > endif > > DO case > CASE m.tcAction="START" > m.lcCurrentStatus="stopped" > srv.StartService() > CASE m.tcAction="STOP" > m.lcCurrentStatus="running" > srv.StopService() > CASE m.tcAction="PAUSE" > m.lcCurrentStatus=IIF(srv.currentstate=SERVICE_RUNNING,"running", "stopped") > srv.PauseService() > CASE m.tcAction="STATUS" > ENDCASE > > WAIT WINDOW NOWAIT NOCLEAR m.tcService + " service is being " + m.tcAction + IIF(m.tcAction='STOP','P','') + 'ED ' + m.tcAnimate > m.lcStatus=IIF(srv.currentstate=SERVICE_RUNNING,"running", "stopped") > FASTDOEVENTS() > srv=.NULL. > ws=.NULL. >ENDDO >WAIT WINDOW NOWAIT m.tcService + " service is " + m.lcStatus + "." >RETURN m.lcStatus > >FUNCTION FastDoEvents > KEYBOARD " " > =INKEY() > DOEVENTS >RETURN >>
>DEFINE CLASS winservices As Collection >#DEFINE SC_MANAGER_CONNECT 1 >#DEFINE SC_MANAGER_LOCK 8 >#DEFINE SC_MANAGER_ENUMERATE_SERVICE 4 > >#DEFINE SERVICE_ACTIVE 1 >#DEFINE SERVICE_INACTIVE 2 >#DEFINE SERVICE_DRIVER 0x0b >#DEFINE SERVICE_WIN32 0x30 > >#DEFINE SERVICE_STOPPED 1 >#DEFINE SERVICE_RUNNING 4 >#DEFINE SERVICE_PAUSED 7 > >#DEFINE SERVICE_START 0x10 >#DEFINE SERVICE_STOP 0x20 >#DEFINE SERVICE_PAUSE_CONTINUE 0x40 >#DEFINE SERVICE_INTERROGATE 0x80 > >#DEFINE SERVICE_CONTROL_STOP 1 >#DEFINE SERVICE_CONTROL_PAUSE 2 >#DEFINE SERVICE_CONTROL_INTERROGATE 4 > >PROTECTED hManager, hLock > hManager=0 > hLock=0 > errorcode=0 > >PROCEDURE Init(cComputerName, cDatabaseName, nServiceType) > THIS.declare > IF VARTYPE(m.cComputerName) <> "C" > cComputerName=Null > ENDIF > IF VARTYPE(m.cDatabaseName) <> "C" > cDatabaseName=Null > ENDIF > > THIS.hManager = OpenSCManager(m.cComputerName, m.cDatabaseName,; > BITOR(SC_MANAGER_CONNECT, SC_MANAGER_LOCK,; > SC_MANAGER_ENUMERATE_SERVICE)) > > THIS.errorcode = IIF(THIS.hManager=0, GetLastError(), 0) > > IF VARTYPE(m.nServiceType)="N" > THIS.EnumServices(m.nServiceType) > ENDIF > >PROCEDURE EnumServices(nServiceType) >#DEFINE ENUM_SERVICE_STATUS_SIZE 36 >#DEFINE SERVICE_STATUS_SIZE 28 > > THIS.ClearEnum > > LOCAL nBufsize, nBytesNeeded, nCount, hResume, nServiceStatus > STORE 0 TO nBytesNeeded, nCount, hResume > nServiceStatus = BITOR(SERVICE_ACTIVE, SERVICE_INACTIVE) > > = EnumServicesStatus(THIS.hManager, nServiceType,; > nServiceStatus, 0, 0,; > @nBytesNeeded, @nCount, @hResume) > > nBufsize = nBytesNeeded > hBuffer = LocalAlloc(0, nBufsize) > hResume = 0 > > = EnumServicesStatus(THIS.hManager, nServiceType,; > nServiceStatus, hBuffer, nBufsize,; > @nBytesNeeded, @nCount, @hResume) > > LOCAL cBuffer, cService, nIndex, hPtr, hServiceName > cBuffer = REPLICATE(CHR(0), nBufsize) > = MemToStr(@cBuffer, hBuffer, nBufsize) > > FOR nIndex=0 TO nCount-1 > LOCAL oService As winservice > oService = CREATEOBJECT("winservice",; > THIS, m.hBuffer, @cBuffer, nIndex) > > THIS.Add(oService, oService.servicename) > oService=Null > NEXT > = LocalFree(hBuffer) >RETURN .T. > >PROCEDURE Destroy > IF THIS.hManager <> 0 > THIS.ClearEnum > THIS.UnlockDatabase > = CloseServiceHandle(THIS.hManager) > THIS.hManager=0 > ENDIF > >FUNCTION GetService(vService) As winservice > LOCAL oService As winservice, ex As Exception > TRY > oService = THIS.Item(vService) > CATCH TO ex > THIS.errorcode = ex.Message > oService = Null > ENDTRY >RETURN oService > >PROTECTED PROCEDURE ClearEnum > DO WHILE THIS.Count > 0 > LOCAL itm As winservice > itm = THIS.Item(1) > itm = Null > THIS.Remove(1) > ENDDO > >FUNCTION GetHManager() >RETURN THIS.hManager > >FUNCTION IsDatabaseLocked >RETURN (THIS.hLock <> 0) > >FUNCTION LockDatabase > IF THIS.hLock = 0 > THIS.hLock = LockServiceDatabase(THIS.hManager) > ENDIF > THIS.errorcode = IIF(THIS.hLock=0, GetLastError(), 0) >RETURN (THIS.hLock <> 0) > >FUNCTION UnlockDatabase > IF THIS.hLock <> 0 > = UnlockServiceDatabase(THIS.hLock) > THIS.hLock = 0 > ENDIF >RETURN (THIS.hLock = 0) > >PROTECTED PROCEDURE declare > DECLARE INTEGER GetLastError IN kernel32 > DECLARE INTEGER LockServiceDatabase IN advapi32 INTEGER hSCManager > DECLARE INTEGER CloseServiceHandle IN advapi32 INTEGER hSCObject > DECLARE INTEGER UnlockServiceDatabase IN advapi32 INTEGER ScLock > DECLARE INTEGER LocalFree IN kernel32 INTEGER hMem > > DECLARE RtlMoveMemory IN kernel32 As StrToMem; > INTEGER Dest, STRING @Src, INTEGER nLength > > DECLARE RtlMoveMemory IN kernel32 As MemToStr; > STRING @dest, INTEGER src, INTEGER nLength > > DECLARE INTEGER LocalAlloc IN kernel32; > INTEGER uFlags, INTEGER uBytes > > DECLARE INTEGER OpenSCManager IN advapi32; > STRING lpMachineName, STRING lpDatabaseName,; > LONG dwDesiredAccess > > DECLARE INTEGER OpenService IN advapi32; > INTEGER hSCManager, STRING lpServiceName,; > LONG dwDesiredAccess > > DECLARE INTEGER EnumServicesStatus IN advapi32; > INTEGER hSCManager, LONG dwServiceType, LONG dwServiceState,; > INTEGER lpServices, LONG cbBufSize, LONG @pcbBytesNeeded,; > LONG @lpServicesReturned, LONG @lpResumeHandle > > DECLARE INTEGER StartService IN advapi32; > INTEGER hService, LONG dwNumServiceArgs,; > INTEGER lpServiceArgVectors > > DECLARE INTEGER ControlService IN advapi32; > INTEGER hService, LONG dwControl,; > STRING @lpServiceStatus >ENDDEFINE > >DEFINE CLASS winservice As Session >PROTECTED oWinServices, hService > hService=0 > errorcode=0 > servicename="" > displayname="" > servicetype=0 > currentstate=0 > controlsaccepted=0 > win32exitcode=0 > serviceexitcode=0 > checkpoint=0 > waithint=0 > >PROCEDURE Init(oWinServices, hBuffer, cBuffer, nIndex) > THIS.oWinServices = m.oWinServices > > LOCAL cService, hPtr > cService = SUBSTR(cBuffer,; > (nIndex*ENUM_SERVICE_STATUS_SIZE)+1,; > ENUM_SERVICE_STATUS_SIZE) > > THIS.ConvertStatusInfo(SUBSTR(cService, 9)) > > hPtr = buf2dword(SUBSTR(cService, 1,4)) - hBuffer + 1 > THIS.servicename = THIS.GetName(@cBuffer, hPtr) > > hPtr = buf2dword(SUBSTR(cService, 5,4)) - hBuffer + 1 > THIS.displayname = THIS.GetName(@cBuffer, hPtr) > >PROCEDURE Destroy > THIS.CloseServiceHandle > >PROTECTED FUNCTION GetName(cBuffer, hPtr) > IF (hPtr <= 0) OR hPtr >= LEN(cBuffer) > RETURN "" > ENDIF > > LOCAL cName, ch > cName = "" > DO WHILE hPtr < LEN(cBuffer) > ch = SUBSTR(cBuffer, m.hPtr, 1) > IF m.ch = CHR(0) > EXIT > ENDIF > cName = cName + m.ch > hPtr = hPtr + 1 > ENDDO >RETURN cName > >FUNCTION StartService >* 1055=ERROR_SERVICE_DATABASE_LOCKED >* A call to the StartService function to start a service >* in a locked database fails. No other service control manager >* functions are affected by a lock. > THIS.errorcode = 0 > IF NOT THIS.OpenServiceHandle(0x90) > RETURN .F. > ENDIF > > LOCAL LockStatus > LockStatus = THIS.oWinServices.IsDatabaseLocked() > > IF THIS.oWinServices.UnlockDatabase() > IF StartService(THIS.hService, 0,0) = 0 > THIS.errorcode = GetLastError() > ENDIF > IF m.LockStatus > THIS.oWinServices.LockDatabase > ENDIF > ENDIF > THIS.CloseServiceHandle >RETURN (THIS.errorcode <> 0) > >PROCEDURE StopService > THIS.ControlService(SERVICE_STOP, SERVICE_CONTROL_STOP) > >PROCEDURE PauseService > THIS.ControlService(SERVICE_PAUSE_CONTINUE, SERVICE_CONTROL_PAUSE) > >PROTECTED PROCEDURE CloseServiceHandle > IF THIS.hService <> 0 > = CloseServiceHandle(THIS.hService) > THIS.hService = 0 > ENDIF > >PROTECTED FUNCTION OpenServiceHandle(nAccess) > THIS.CloseServiceHandle > THIS.hService = OpenService(THIS.oWinServices.GetHManager(),; > THIS.servicename, nAccess) > THIS.errorcode = IIF(THIS.hService=0, 0, GetLastError()) >RETURN (THIS.hService <> 0) > >PROTECTED FUNCTION ControlService(nOpenFlag, nCtrlFlag) > THIS.errorcode = 0 > IF NOT THIS.OpenServiceHandle(nOpenFlag) > RETURN .F. > ENDIF > > LOCAL cStatusInfo > cStatusInfo = REPLICATE(CHR(0), SERVICE_STATUS_SIZE) > IF ControlService(THIS.hService, nCtrlFlag, @cStatusInfo) = 0 > THIS.errorcode = GetLastError() > ENDIF > THIS.CloseServiceHandle >RETURN .T. > >FUNCTION UpdateStatusInfo > THIS.errorcode = 0 > IF NOT THIS.OpenServiceHandle(SERVICE_INTERROGATE) > RETURN .F. > ENDIF > > LOCAL cStatusInfo > cStatusInfo = REPLICATE(CHR(0), SERVICE_STATUS_SIZE) > > IF ControlService(THIS.hService,; > SERVICE_CONTROL_INTERROGATE, @cStatusInfo) = 0 > THIS.errorcode = GetLastError() > ELSE > THIS.ConvertStatusInfo(cStatusInfo) > ENDIF > THIS.CloseServiceHandle >RETURN .T. > >PROTECTED PROCEDURE ConvertStatusInfo(cStatusInfo) > THIS.servicetype = buf2dword(SUBSTR(cStatusInfo, 1,4)) > THIS.currentstate = buf2dword(SUBSTR(cStatusInfo, 5,4)) > THIS.controlsaccepted = buf2dword(SUBSTR(cStatusInfo, 9,4)) > THIS.win32exitcode = buf2dword(SUBSTR(cStatusInfo, 13,4)) > THIS.serviceexitcode = buf2dword(SUBSTR(cStatusInfo, 17,4)) > THIS.checkpoint = buf2dword(SUBSTR(cStatusInfo, 21,4)) > THIS.waithint = buf2dword(SUBSTR(cStatusInfo, 25,4)) > >ENDDEFINE > >FUNCTION buf2dword(lcBuffer) >RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ; > BitLShift(Asc(SUBSTR(lcBuffer, 2,1)), 8) +; > BitLShift(Asc(SUBSTR(lcBuffer, 3,1)), 16) +; > BitLShift(Asc(SUBSTR(lcBuffer, 4,1)), 24) >