service_api

Discussions related to Visual Prolog
pschoenung
Posts: 2
Joined: 10 May 2011 10:13

service_api

Unread post by pschoenung » 8 Feb 2012 11:31

Have somebody an example for creating a service with visual prolog ?
thanks for help

Gildas Menier
Posts: 15
Joined: 8 Jun 2004 23:01

Unread post by Gildas Menier » 9 Feb 2012 21:41

Arsaniit is down for the moment but his may help you (sorry for the format it is a copy/past of the arsaniit page) :

(beware, DO NOT try to run a service 32 bit on an OS 64 bits - VP is 32 bits, so it can only be used to build 32 bits exe)

Regards

Gildas



A Service is a program launched at machine's startup (or as needed) : it doesn't directly rely on user or session - think of it as a kind-of custom driver (not really accurate, but you get the idea). This vp_service extension makes the creation of service in Visual Prolog easier (you may want to have a look at MSDN anyway) and uses the service_api provided by PDC.

This documentation explains how to build a service using Visual Prolog, how to install it (uninstall it), run, start, pause or resume it : Within this scope, service is a Visual Prolog program able to start with the computer (even with no session).


SCM and services

First important thing : launch a command console (start -> execute -> cmd) and execute the following command :

services.msc

This should open a window with the list of registered services. A double click on a name in the list opens a dialog with some info.

This dialog shows the current state of the SCM (service control manager) for the selected service.

Load this project with Visual Prolog and compile it (do not execute/run it !).

Now, open a command console in the exe directory of this project (I suggest using the "open command window here" shell extension : it is a very handy tool provided (free) by Microsoft : just right click on a folder and open a command shell in this context - check also the orhter powertoys)

now, type in "service install"

after awhile, this should display something like "service installed".

Back to the scm window : right click and refresh the display : there is now a 'VisualPrologService' in the list.

This service is not started : you still have to manually start it (it is possible to start this service automatically of course). Just choose 'start service' in the SCM and that's it.

This dummy service writes some trace in c:/log.txt. You can browse and open this file and see by yourself what it does : this service writes the current time each 2s.

Using the SCM, you can pause, resume, stop, restart the service.

To uninstall the service, stop it first and type in "service uninstall"

If you now refresh the display of the SCM window, the service should be gone.

Setting a service in Visual Prolog

Now, for the Visual Prolog's part :

open the servicetest.pro file : this is a good start template for you service project.

first thing : name your service :

Code: Select all

        vp_service::setServiceName("VisualPrologService"),
Then,if you want to attach a description to the service, use :

Code: Select all

          vp_service::setServiceDescription("Test Service written in VP7.2 : writes time each 2s in c:/log.txt\n"),
The install / start / uninstall :

Code: Select all

    exec("install") :-         vp_service::setServiceDescription("Test Service written in VP7.2 : writes time each 2s in c:/log.txt\n"),                 console::init(),         if not(vp_service::tryInstallService())         then             console::write("Unable to install the service\n")         else             console::write("Service installed\n")         end if,     !.%         exec("uninstall") :-         console::init(),         if not(vp_service::tryUnInstallService())         then             console::write("Unable to uninstall the service\n")         else             console::write("Service uninstalled\n")         end if,     !.%       exec("start") :-         console::init(),         if not(vp_service::tryStartService())         then             console::write("Unable to start the service\n")         else             console::write("Service Started\n")         end if,     !.%
The tryInstall fails if it is not possible to register the service to the SCM. Note that you may want to install a service that will run automatically the next time the computer starts : just use :

Code: Select all

        if not(vp_service::tryInstallService("auto"))
Perhaps the most important thing is the last exec(_) part :

Code: Select all

        exec(_) :-         vp_service::setService(serviceMethod),                   vp_service::setStart(startMethod),         vp_service::setPause(pauseMethod),         vp_service::setResume(resumeMethod),         vp_service::setStop(stopMethod),                 vp_service::runService()     .%
It is VERY important to understand that the service won't be called by the SCM if a console::init() is executed prior this part of code (so check the run method in the main.pro source, and remove the console::init() !!)

You shouldn't call this exec method yourself : when the service is started, the SCM runs service.exe without any arguments in the appropriate context. Calling yourself service.exe without any args won't work as expected.

The startMethod (if set) is called by the SCM before the service is started :

Code: Select all

class predicates     startMethod : vp_service::serviceCallback.     clauses         startMethod(_ServiceName) :-             FileName = "c:/log.txt",             if file::existExactFile(FileName) then file::delete(FileName) end if,             file::appendString(FileName, "Service Started\n",false),         !.%


Samewise, the pauseMethod is called if/when the service is paused (same thing for Resume or Stop).

Code: Select all

class predicates     serviceMethod : vp_service::serviceCallback.     clauses         serviceMethod(_ServiceName) :-             T = time::new(),             Info = string::format(" Time now is %s\n",T:format("hh:mm:ss")),             file::appendString("c:/log.txt", Info,false),             programControl::sleep(2000),         !.%
This service is actually enclosed in an endless loop (coded as a thread). You should provide a programControl::sleep therefore.

Do not attempt to console::write or use some GUI : a service is not supposed to interact with the user (at least not in this vp_service mini API).

Ok, now if you want to build your own service :
  • Make a new console project
  • Remove 'console::init' from main.pro
  • copy the vp_extensions folder to your project
  • add the vp_extensions.pack and vp_service.pack
  • copy the servicetest.pro content to your class and customize it.
Feel free to ask if you have trouble / Problem.

I assume this API is bug free : I used this extended (small) api to build a service (using also SCS) able to control remotely a PC without any trouble... Gildas

Code: Select all

domains     serviceCallback = (string ServiceName) procedure.     predicates     classInfo : core::classInfo.     % @short Class information  predicate.     % @detail This predicate represents information predicate of this class.     % @end     predicates     setServiceName: (string ServiceName) procedure (i).         % @short Sets the name of the current service.         % @detail This predicates sets the name of the service currently managed.         % @end             setServiceDescription: (string Description) procedure (i).         % @short Describes the service         % @detail This describes the service : this text can be found in the service.msc under properties.         % @end             setStart: (serviceCallback Method) procedure (i).         % @short Callback method for start         % @detail This Method is called when the service has been successfully started         % @end             setService: (serviceCallback Method) procedure (i).         % @short Callback method for the service         % @detail This Method is actually the service to run : it is enclosed in an endless loop - you should provide a ProgramControl::sleep to manage the loop speed.         % @end             setStop: (serviceCallback Method) procedure (i).         % @short Callback method for stop         % @detail This Method is called when the service has been successfully stopped         % @end             setPause: (serviceCallback Method) procedure (i).         % @short Callback method for pause         % @detail This Method is called when the service has been successfully paused         % @end             setResume: (serviceCallback Method) procedure (i).         % @short Callback method for resume         % @detail This Method is called when the service has been successfully resumed         % @end             tryInstallService:(string Mode) determ.         % @short Tries to install the service         % @detail This tries to install the service in the SCM. Mode can be "auto"(system startup), "demand"(use the startService or tryStartService), "boot"(for drivers only), "system" (only for drivers / IoInitSystem)         % @fail Fails if an error occurs and the service can't be installed properly         % @end             tryInstallService:() determ.         % @short Tries to install the service         % @detail This tries to install the service in the SCM. Same as tryInstallService("demand")         % @fail Fails if an error occurs and the service can't be installed properly         % @end         tryUnInstallService:() determ.         % @short Tries to UNinstall the service         % @detail This tries to UNinstall the service in the SCM         % @fail Fails if an error occurs and the service can't be UNinstalled properly         % @end         tryStartService:() determ.         % @short Tries to start the service         % @detail This tries to start the service in the SCM         % @fail Fails if an error occurs and the service can't be started properly         % @end         runService: ().         % @short Access to service for th SCM         % @detail This method is the main method for the SCM : you shouldn't call this method your self.         % @end
Attachments
testservice.zip
project
(18.86 KiB) Downloaded 253 times

pschoenung
Posts: 2
Joined: 10 May 2011 10:13

Unread post by pschoenung » 16 Feb 2012 5:55

Thank you for this example this is a good startpoint for me

regards Peter

User avatar
whyteian
Posts: 6
Joined: 22 Sep 2007 15:07

Access to arsaniit.com

Unread post by whyteian » 19 Jul 2013 17:52

Gildas Menier wrote:Arsaniit is down for the moment but his may help you (sorry for the format it is a copy/past of the arsaniit page) :
Does anyone know the status of the arsaniit.com website by any chance? I have been trying to access a few resources over the last couple of weeks and noticed this previous post from last year noting the site was down. Thanks.

IanB
Ian B. Whyte
London, Ontario, Canada

Post Reply