FWH app as Service

FWH app as Service

Postby Jeff Barnes » Fri Mar 24, 2017 3:51 pm

I have three different apps that I need to run as a service.
Two of them work perfectly. The third however will not function correctly.

The first two simply grab data from a text file and insert the data into a dbf.

The third app is trying to create a PDF using the built-in FWH Report (Report oReport.....)

Has anyone ever tried doing something like this and had success ?
The app works perfectly if run as a regular program.

I've even tried running the app as a service via AlwaysUp and FireDeamon but no luck.

I added some logging info in my app and it looks like it never gets to the function "AddData()"

When run as a regular program my log file shows:
03/24/17 09:13:05*******CertusReports Started*****
03/24/17 09:13:05 Initial Timer Started
03/24/17 09:13:10 Function GenReport: Processing: 20170324085918677.txt
03/24/17 09:13:10 Function GenReport: Option: Date Confirmed, Site: ALL, From: 20170222, To: 20170324, RepFile: 20170324085918677.pdf
03/24/17 09:13:10 Function DoReport called
03/24/17 09:13:11 Function AddData called
03/24/17 09:13:14 *** Report Generated ***


When run as a service my log file shows:
03/24/17 09:11:33*******CertusReports Started*****
03/24/17 09:11:33 Initial Timer Started
03/24/17 09:11:38 Function GenReport: Processing: 20170324085918677.txt
03/24/17 09:11:38 Function GenReport: Option: Date Confirmed, Site: ALL, From: 20170222, To: 20170324, RepFile: 20170324085918677.pdf
03/24/17 09:11:38 Function DoReport called

Any ideas??

Code: Select all  Expand view

Function DoReport(cNote)
    PRIVATE oReport
    oLog:Add(DTOC(Date())+"  "+TIME()+" Function DoReport called")
        DEFINE FONT oFontRep NAME "ARIAL" SIZE 0,-9

    cSave := cRepFile
    cSave2:= "C:\Certus\Temp\"+cRepFile

    PRINTER oPrn FILE cSave2

    REPORT oReport ; //PREVIEW ;
        FONT oFontRep ; 
        HEADER ALLTRIM("
Certus Management Report"+SPACE(20)+"Date: "+DTOC(DATE()))+"  Time: "+Time(),  ;
                 ALLTRIM(cSave),  ;
                 ALLTRIM(cNote),  ; 
                 "
" ;
                 CENTER ;
        TITLE "
";
                 LEFT;
        FOOTER "
Certus Management report" +Space(40) +  ;
                 "
Page Number: " + ALLTRIM(Str(oReport:nPage,3)) CENTER ;
        TO DEVICE oPrn
       

        COLUMN TITLE "
Patient Name        " DATA " "  //GRID 1  
        COLUMN TITLE "
Gender"           DATA " "  GRID 1  
        COLUMN TITLE "
D.O.B.   "        DATA ""   GRID 1  

        COLUMN TITLE "
MRN / ID     " DATA " "  GRID 1  
        COLUMN TITLE "
Reading Phy   "   DATA " "  GRID 1  
        COLUMN TITLE "
Referring Phy           " DATA " "  GRID 1  
        COLUMN TITLE "
Type "    DATA ""   GRID 1  

        COLUMN TITLE "
Test Date"        DATA " "  GRID 1  
        COLUMN TITLE "
Days"                 DATA " "  LEFT GRID 1  
        COLUMN TITLE "
Imported"         DATA " "  LEFT GRID 1  
        COLUMN TITLE "
Confirmed"        DATA " "  LEFT //GRID 1  
  ENDREPORT
    
  ACTIVATE REPORT oReport on init AddData()
  oFontRep:End()
  CLOSE TESTDB
  oLog:Add(DTOC(Date())+"
 "+TIME()+" *** Report Generated ***")
Return Nil

Function AddData()
    LOCAL cText, nCol, nRow
    oLog:Add(DTOC(Date())+"
 "+TIME()+" Function AddData called")
    nRow := 1
        nCol := 1

    DO WHILE ! EOF()
        oReport:StartLine()
        oReport:Say(nCol, LEFT(ALLTRIM(TESTDB->Last)+"
, "+ALLTRIM(TESTDB->First),26) )
        oReport:Say(nCol+1, LEFT(TESTDB->Gender,6) )
        oReport:Say(nCol+2, LEFT(TESTDB->DOB,10) )
        oReport:Say(nCol+3, LEFT(TESTDB->MRN,17) )
        oReport:Say(nCol+4, LEFT(TESTDB->ATTDOC,18) )
        oReport:Say(nCol+5, LEFT(TESTDB->REFDOC,25) )
        oReport:Say(nCol+6, LEFT(TESTDB->TestType,6) )
        oReport:Say(nCol+7, LEFT(TESTDB->TESTDATE,10) )

        IF ! EMPTY(ALLTRIM(TESTDB->DateConf)) .and. ! EMPTY( STRTRAN(DTOC(TESTDB->ImportDate),"
/",""))
            dImportDate:= STOD(DTOS(TESTDB->IMPORTDATE))
            dConfirmDate:= STOD(DTOS(CTOD(TESTDB->DATECONF)))
            oReport:Say(nCol+8, ALLTRIM(STR( ABS(dConfirmDate - dImportDate) )))
        ELSE
            oReport:Say(nCol+8, "
" )
        ENDIF

        oReport:Say(nCol+9,     LEFT(DTOC(TESTDB->IMPORTDATE),8 ) )
        oReport:Say(nCol+10, LEFT(TESTDB->DATECONF,8) )

        oReport:EndLine()
        nRow++
        IF nRow = 55
            oReport:EndPage()
            nRow := 1
        ENDIF
        SKIP
    ENDDO
Return Nil 

Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Re: FWH app as Service

Postby rhlawek » Sat Mar 25, 2017 3:42 pm

Jeff,

I'm guessing a bit here, but it seems possible that your service is trying to open up a window on the desktop but can't because, being a service, it doesn't actually have a desktop.

Two things:

1) Using the services control panel, modify your service to allow desktop interaction. (Done via a checkbox on the Log on tab.) This won't necessarily fix your problem, but it may help you see the problem.
2) Add a bit more logging to the DoReport() function to better determine how far into the function you are getting before it hangs. (I'm guessing it hangs at ACTIVATE REPORT)
User avatar
rhlawek
 
Posts: 194
Joined: Sun Jul 22, 2012 7:01 pm

Re: FWH app as Service

Postby reinaldocrespo » Sat Mar 25, 2017 5:32 pm

Hello Jeff;

TReport does try to access the GUI interface. Services can't do that.

BTW- would you share your code for the simples of services you have working with me? Please send to reinaldo dot crespo at gmail

Thank you,


Reinaldo.
User avatar
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: FWH app as Service

Postby rhlawek » Sat Mar 25, 2017 7:53 pm

Reinaldo,

The test code in ~\harbour\contrib\hbwin\tests\service.prg shows how to build an executable that can be installed and run as a service without the need for any external utilities. It's very straightforward. I used that code as the basis to create a service manager class that allows me to build a single executable that can run as a service, on the console, or as a GUI, which fits my needs perfectly on Windows, plus it handles running as a daemon or console app under Linux or MacOS. (I don't have a GUI hooked into it yet for Linux or MacOS, but that's next.)

Robb
User avatar
rhlawek
 
Posts: 194
Joined: Sun Jul 22, 2012 7:01 pm

Re: FWH app as Service

Postby reinaldocrespo » Sat Mar 25, 2017 8:17 pm

Thank you Robb;

I can't find hbwin on my xharbour contrib directory. Would you mind sharing that .prg?

Reinaldo.
User avatar
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: FWH app as Service

Postby TimStone » Sat Mar 25, 2017 8:59 pm

Robb,

I tried last year to get a service build and had no success. I'm up to try again.

1) Is the program testsvc.prg ? I found that in my contrib, but not a service.prg
2) Do you have a .mak script for Harbour / MSVC for this ?
3) What libraries does it require in the build ?

I have a serious need to have a service running ( no GUI ) but just have not had luck making it happen. Antonio and I spent a lot of time trying, but it simply would not behave. Hopefully I can get this going.

I'm using Antonio's release of the MS Harbour libs ( 2015 ), FWH 17.02, and MSVC from Studio 2015 ( Community ).

Thanks for sharing.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: FWH app as Service

Postby rhlawek » Sat Mar 25, 2017 10:04 pm

I use Viktor's 3.4 fork, but I just checked out the main stream 3.2 code and the file is contrib\hbwin\tests\service.prg there as well. I don't see testsvc.prg.

If you want to look at a real implementation have a look in contrib\hbnetio\utils\hbnetio, there you should see a file named _winsvc.prg, which is what hbnetio uses to install itself as a service. It's pretty close to what is in the service.prg mentioned so either would bring you up to speed. In the past I used my own C implementation to do this but I stopped using my code after discovering what came along natively with harbour.

Some service gotcha's:

1) You can use OutputDebugString() inside a service to write debug information to a debug viewer, but the debug viewer needs to be run as administrator, and it needs to be configured to capture Global Win32 messages in order to show the debug info.

2) Writing to the desktop is generally not good. It can be done, but personally I always avoid this. If you build with a GUI such as FWH innocuous things such as qout()/? which get redirected to a popup window will hang the service. FWH has an Alert() function (which conflicts with a function by the same name in harbour btw) that is called at times from within the FWH libraries, and that will hang the service. FWH assumes that it is always interacting with a user on the console, not as a headless service. I get around this by avoiding making FWH calls from within the service itself. In the case of the Alert() function I have yet another Alert() function within my code which I use to force the alert to a log instead of allowing it to try to open a window on the desktop.

I'm sure there are more that I am not remembering a the moment, but those are the big ones I recall.

Robb
User avatar
rhlawek
 
Posts: 194
Joined: Sun Jul 22, 2012 7:01 pm

Re: FWH app as Service

Postby TimStone » Mon Mar 27, 2017 3:55 pm

The other part of the question was, do you have a .mak file to build a service with MSVC and Harbour ? I need to know which libraries actually need to be included.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: FWH app as Service

Postby Marc Venken » Mon Mar 27, 2017 6:35 pm

Sorry to jump in, but the services that are discused here are not the same as activating a dialog with the HIDDEN command ?
like :

ACTIVATE WINDOW oMain HIDDEN ON INIT ( OTimer:Activate() )

I'm also working on a small program that will LOG data from a PBX system with a CTI program.

This works, the program is hidden and will popup when a call is comming in.

The services discused here are for other purposes then I do now ?
Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1434
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: FWH app as Service

Postby Jeff Barnes » Tue Mar 28, 2017 12:17 pm

Hi Reinaldo,

The services that I have working are all basic FW code. nothing special.
I create a Window and set a timer to run my functions.
None of my functions try to display anything. Just used to extract text from files and insert into my dbf.
Is there any way to not have TReport try to access the GUI interface?

Robb,
I do have the the service set to allow desktop interaction.
You are correct, it looks like it hangs at "Activate Report"
The only thing that is shown when I click on the Interactive Desktop notice is the Window I use to start off the program. This works well for my other apps that are running as a service.
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Re: FWH app as Service

Postby reinaldocrespo » Tue Mar 28, 2017 11:01 pm

Hey Jeff;

If this is a regular FW program set to execute a given procedure/function with a timer, then it is really **not** a service. Robb's answers assumes you are speaking of a real windows service.

In MS-Windows a service is a computer program that operates in the background and has no access to desktop windows or keyboard input. It is similar in concept to a Unix daemon. A service can be stopped-started-restarted using the task manager. One of the advantages of a service is that Windows can load the service without need of a user logging in. Just turn the computer on and it is running.

Reinaldo.
User avatar
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: FWH app as Service

Postby Jeff Barnes » Tue Mar 28, 2017 11:16 pm

Hi Reinaldo,

That's exactly why I need to run these apps as a service.
I need these running without any users logged in.

I realize these are not true windows services but I can get them to act as services as they don't require any user interaction.

I'm just stuck on getting the report part working as a service.
Since as mentioned, the report makes use of a gui, I guess I'm out of luck on that one.
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Re: FWH app as Service

Postby reinaldocrespo » Tue Mar 28, 2017 11:28 pm

...hum, I wonder if a service could "spawn" or initiate a regular win32 program sending certain parameters or after certain data to a file and let that regular windows program take care of creating the report using FW TReport class after reading said data from the log file or dbf. Ideas anyone?

Reinaldo.
User avatar
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: FWH app as Service

Postby Jeff Barnes » Tue Mar 28, 2017 11:41 pm

I tried using WinExec to launch my report app from one of the apps I have working as a service ... no luck. Exact same issue :(
This I tried when logged in and logged out. Same result either way.
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada

Re: FWH app as Service

Postby rhlawek » Wed Mar 29, 2017 5:02 am

Responding to Reinaldo's comment about spawning a Win32 app from a service and have the spawned app interact with the desktop. Yes, this works. I have 3 apps in production that work this way, calling apps that were written by somebody other than me. The service still needs to be set to interact with the desktop, a user account has to be logged in, and unless the program being called starts and exits without user interaction a mechanism is needed to close the called app. In my case one of the apps has a socket interface that is controlled via the service, in the other cases I wound up doing a FindWindow then sending a windows message to exit the spawned app.

I just did a quick read of the report class, it seems possible that it could be modified to allow a report to be generated/printed/saved/sent without needing user interaction, but I don't have time to figure that out at the moment, and I could be wrong. This was one of my specific areas of interest in EasyReport, it's been a while since I looked at that code but if I recall correctly the erstart class does this.
User avatar
rhlawek
 
Posts: 194
Joined: Sun Jul 22, 2012 7:01 pm

Next

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 48 guests