Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Why is a dummy table automatically created when ran as service 1

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi, I'm adding "run as a service" support to my app. The app runs fine in development and as an .exe. However when ran as a service using a system account that interacts with the desktop it prompts for a table name. It doesn't matter what table I choose, it fails and automatically creates a dummy table and places it in the dbc.

Anyone know how I should troubleshoot and/or whay I should be looking for?

VFP9sp2 on XPproSp3

Thanks, Stanley
 
>> Come back with the end of the cover.log and then we'll see.

I'm back with the end of the coverage log and a screencast. Go to
Now what?



,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,6
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,6
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,6
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,6
0.000009,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,6
,,syncexport,125,syncexport.fxp,5
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000007,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
10.393587,,phd,10,phd.fxp,6
0.000019,,phd,12,phd.fxp,6
0.000006,,phd,13,phd.fxp,6
0.000006,,phd,14,phd.fxp,6
0.000005,,phd,15,phd.fxp,6
0.000005,,phd,16,phd.fxp,6
0.000005,,phd,17,phd.fxp,6
0.000005,,phd,18,phd.fxp,6
0.000005,,phd,19,phd.fxp,6
0.000067,,phd,20,phd.fxp,6
0.000020,,phd,21,phd.fxp,6
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000007,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.003655,,phd,22,phd.fxp,6
0.002067,,phd,23,phd.fxp,6
0.000016,,phd,24,phd.fxp,6
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000010,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000387,,phd,25,phd.fxp,6
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000007,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,phd,26,phd.fxp,6
 
OK, now that I have commented out the whole phd.prg, the messagebox and table selector dialog are gone, however its doing no work... See notes after the log...


The last lines the coverage.log are:

0.000006,,phd,76,phd.fxp,6
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000007,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000006,,phd,76,phd.fxp,6
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000007,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000008,,phd,76,phd.fxp,6
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000007,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000006,,phd,76,phd.fxp,6
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000007,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000006,,phd,76,phd.fxp,6
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000007,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000006,,phd,76,phd.fxp,6
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,7
0.000007,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,7
,,phd,76,phd.fxp,6

This segment of the log file is duplicated from about line 4,500 thru 1,521,000 as its hitting a loop or something...

Line 76 in the phd.prg file is the last line, and all lines are commented out...
Line 3 in the frmsyncer.error routine = Do Case
Line 4 = Case nError = 1705 && 1705 File Access Denied
Line 18 = Case nError = 3 && 3 File In Use
Line 32 = Otherwise
Line 33 = Endcase

How do I troubleshoot, as messageboxes will show, but set step will not? I was hoping the coverage log would be more helpful. How do I troubleshoot?

 
Well, from the log you can see the error method of form syncer runs. So look further up and see where you first enter the error method. There is some bug you need to fix first, maybe has nothing to do with phd.

in the first post, line 33 of frmsyncer.error is the last line executed before foxpro jumps into phd.prg, line 10. This is interesting, as the if .f. in phd.prg is in line 8, the way you showed it, and there is no way to enter line 10 first.

It would be interesting to see the error method of frmsyncer and expecially up to line 33.

Bye, Olaf.
 
Now that I looked at the screencast. Can you show the par tof the log, where the phd prg is mentioned the first time, where it is entered?

And while we're at it: An exe running as a service must respond to certain windows messages. No VFP EXE does so. The switch enabling interaction with the desktop does not help for that problem. PErhaps using a wrapper like srvany already fixes your problem.

That said I don't know how that could make the phd.prg run from after if .f.

It might be interesting to see a decompilation of the exe to see if the if .f. line really is if .f. in object code, and not via any weird mechanism translated to some other if or skipped or whatever.

Bye, Olaf.
 
Another question that comes to mind is: Is the line use ? part of the original phd.prg. do you still have the installation package and could restore the original state?

As the phd.prg repeatedly is logged, alternating with the error method, I suspect it's no the error method calling phd, but phd erroring. But maybe your error method contains some phd command which in turn errors again an you get the endless loop.

As I already said the initial entry into the phd.prg and what happens right before that is the interesting part.

It might be, that you should never switch on the "(re)compile all" option in the build of the vfp project manager, as that changes phd.fxp, maybe phd is directly jumping to some adress in the original version of phd.fxp via some command you issue. And maybe that has become the wrong adress through the phd.prg being recompiled to a differing phd.fxp.

Maybe phd also tells in it's instructions to not incude the prg into the exe but keep it seperate. I don't know phd besides that it is a full text indexing tool. I ever used it.

Assumptions, assumptions. Most interesting is the first entry into the phd.prg for now, then we'll see further.

Bye, Olaf.
 
>> It would be interesting to see the error method of frmsyncer and expecially up to line 33.

Here OlafDoschke is the entire error routine. Line 33 is the last line...

Lparameters nError, cMethod, nLine

Do Case
Case nError = 1705 && 1705 File Access Denied
If Upper(gcUserLevel) = "ADMIN"
Messagebox("Maintenance Procedures are Currently Running... Please Try Again Later !" + Chr(13) + ;
CHR(13) + "The actual code and message is: " + Alltrim(Str(nError)) + ;
" - File Access Denied on line " + Alltrim(Str(nLine)) + Chr(13) + ;
" in " + Alltrim(cMethod) + ".", 0+48, "Message... Stan-Lyn & Associates, Inc.")
Else
Messagebox("Maintenance Procedures are Currently Running... Please Try Again Later !", 0+48, ;
"Stan-Lyn & Associates, Inc.")
Endif

Thisform.AbortForm = .T.
Return

Case nError = 3 && 3 File In Use
If Upper(gcUserLevel) = "ADMIN"
Messagebox("Maintenance Procedures are Currently Running... Please Try Again Later !" + Chr(13) + ;
CHR(13) + "The actual code and message is: " + Alltrim(Str(nError)) + ;
" - File In Use on line " + Alltrim(Str(nLine)) + Chr(13) + ;
" in " + Alltrim(cMethod) + ".", 0+48, "Message... Stan-Lyn & Associates, Inc.")
Else
Messagebox("Maintenance Procedures are Currently Running... Please Try Again Later !", 0+48, ;
"Stan-Lyn & Associates, Inc.")
Endif

Thisform.AbortForm = .T.
Return

Otherwise
Endcase
 
OK, here is an excerpt from the coverage log showing the last line before the error routine starts...

0.000007,,freespace,2265,syncexport.fxp,6
0.000008,,syncexport,50,syncexport.fxp,5
0.000006,,syncexport,53,syncexport.fxp,5
0.000005,,syncexport,54,syncexport.fxp,5
--> last line before error 0.000253,,syncexport,56,syncexport.fxp,5
,,frmsyncer.error,3,c:\stan-lyn\syncdri\forms\syncer.sct,6
,,frmsyncer.error,4,c:\stan-lyn\syncdri\forms\syncer.sct,6
,,frmsyncer.error,18,c:\stan-lyn\syncdri\forms\syncer.sct,6
0.000009,,frmsyncer.error,32,c:\stan-lyn\syncdri\forms\syncer.sct,6
0.000008,,frmsyncer.error,33,c:\stan-lyn\syncdri\forms\syncer.sct,6
0.000020,,syncexport,57,syncexport.fxp,5


and, here is an excerpt from the syncexport.fxp routine which contains line 56 near the bottom...

lcTaskName = Alltrim(TASK.task_Name)
lcTaskType = Alltrim(TASK.task_type)
lcDbcDri = Alltrim(TASK.active_dbc)
lcOldDeleted = Set('DELETED')

Private pcSystemID, pcOldErrorHandler, pnSystemPID, pnQuit, pcCurTable, ;
pcExportMemoName, pcUpLoad, pnSystemVersion

pnQuit = 0
Do FreeSpace With pnQuit

If pnQuit = 999
Return
Else
pnQuit = 0
Endif

--> Line 56 Open Database (lcDbcDri) Shared
Set Database To (lcDbcDri)

Private pcSystemID, pcOldErrorHandler, pnSystemPID, pnQuit, pcCurTable, ;
 
>> Is the line use ? part of the original phd.prg

Yes, as I have never changed anything in it ever... No need to as it always worked until I start this "run as a service" stuff which is my first attempt, and I'm or vfp is failing miserably at it...

But, I'm learning some really good advanced troubleshooting stuff...

Any idea on how to step thru the code when in this "run as a service" mode, either on screen or to a debug output file, or any other way?


>> I suspect it's no the error method calling phd, but phd erroring.

You are right, as it appears that the call to the dbc is the start of the erroring as shown in a previous post...

and, if the phd.prg routine start out with "If .F." as it does, then how could phd be erroring?



Is there any better way of reading variable values that using a messagebox, as so far its the only window into the code that I can see whats going on. Is there a way to send all the variable values to a file as the code executes?

 
Code:
    Otherwise
Endcase

So in other words, out of the hundreds of different errors that VFP might throw, you're responding to exactly two and completely ignoring the rest?

OTHERWISE should *NEVER* be empty, or you'll forever have absolutely no clue which error you're chasing. If nothing else, add

Messagebox( Transform(Error()) )

--> Line 56 Open Database (lcDbcDri) Shared[/code]

OK, then phd is a complete boondoggle. You've ignored the error on this line, which could be any one of dozens of different errors.
 
I've removed the otherwise from the case statement, with no change in behavior. FWIW, I have never had an issue with an empty otherwise in all my years...

I'm still back to asking for the best way to view values while running as a service, so what would you recommend? I've got to find a better way to troubleshoot, or quit this "run as a service" functionality.

I'm already seeing other issues where the code really needs to be stepped thru. One issue is... its losing its dbc reference when returning to the startup dbc... Also, messageboxes work when they want to, (not reliable). Among others...

 
Hi stanlyn,

ok, so the error routine simply finishes and then vfp continues with the program. That's a different thing than I expected. To me an error handler typicaly would not return to the program execution but halt/quit, as you never can predict the state your application is and so I never thought of a natural return from the error method.

Dan already adressed the empty OTHERWISE section.

The actual error from OPEN DATABASE points to access right problems, a service typically runs with the account LOCAL SERVICE or NT AUTHORITY\NetworkService, and that account may not have the access rights to your database.

But this doesn't demystify why you enter phd.fxp into the IF .F. section. To analyse that, I asked for the first time entering phd.fxp, not the first time entering the error method:

Most interesting is the first entry into the phd.prg for now, then we'll see further.

Bye, Olaf.
 
From position 2:51 for about 10 seconds you show the service properties. And that shows your service runs as Local System account.

That means NT AUTHORITY\LocalService, that account by default has no rights to access network shares or the LAN in general. Even if you are logged in as admin or any other domain account being able to see mapped drive and your program therfore works from "dev" or IDE and as .EXE, this is the culprit of it not bein able to OPEN DATABASE as LocalService.

Even if the database is local, check out the effective rights for LocalService.

Bye, Olaf.
 
Stanlyn,

removing the OTHERWISE from the CASe does in fact not change any behavior, as a missing OTHERWISE does exact the same as an empty OTHERWISE: nothing.

You need to do somthing there by default, eg also at minimum display error number and set Thisform.AbortForm = .T.

As you don't do that your error method simply swallows all other except the two errors you handle and keeps you completely uninformed about other not expected errors happening.

Bye, Olaf.
 
While setting it up to regenerate the coverage.log with the phd errors, I'm now getting errors with this line now in any mode...

goSyncerForm = _vfp.ActiveForm && needed so that the import routines can communicate with the form

Error=1429
Message=ActiveForm not found...

This is a new error, and probably caused by a setting somewhere that I've set trying to get the "run as a service" working. I have it set as 2-Top Level and desktop...

 
Pity, you didn't simply save the log.

In regard to _Vfp.activeform I can't tell about cases it would be unset while a form is active. Doesn't matter what type of form it is.

Even if that form is always existing and the only form, _vfp.activeform only references an active form, another application getting focus will deactivate the vfp form.

So most probably at times this fails your form is visible but not active. The better way to set goSyncerForm would be to set it while calling the form. I know you have an scx from the cover.log (it mentions syncer.sct), so you need

Code:
Public goSyncerForm
DO FORM syncer NAME goSyncerForm LINKED NOSHOW
goSyncerForm.Show()
LINKED is optional, but would make sure the form is dropped, if the variable is released or set NULL.

If you switch to classes - which I would suggest to every developer anyway, as we live in a OOP world - then you'd do

Code:
Public goSyncerForm
goSyncerForm = CreateObject("syncer")
goSyncerForm.Show()

Such a public variable holding a reference to the form will stay the reference no matter if the form is active or not, in both cases.

As a side note:

In case of the scx you can skip the NOSHOW clause and then don't need the call to Show(), but it enables you to set some things after form init and before it getting visible, eg set top/left or anything that may influence the appearance before it appearing. With CreateObject() every visual class is instanciated invisible for you to be able to influence it before showing it.

I won't go into the big plus of OOP, classes and inheritance.

Bye, Olaf.
 
Public goSyncerForm
DO FORM 'Syncer' NAME goSyncerForm LINKED NOSHOW With Alltrim(Prompts)
goSyncerForm.Show()

Why would goSyncerForm evaluate as .F.

Also, the coverage.log was over written and now I've gotten these new issues, which is preventing me generating a new log.



 
Why would goSyncerForm evaluate as .F.

The form failed to instantiate because an error happened when it tried. If an error happens instantiating any contained control, that error percolates out to the container (form) and prevents the whole shooting match from loading.

What does the OTHERWISE condition report in the error handler?
 
As dan said,

if the variable is set .f. the form init failed. Maybe because you followed my recommendation to change database file access rights?

Debug the form init by doing SET STEP ON right before DO FORM and you'll see what fails.

Bye, Olaf.
 
Another question: Why did you just mention _vfp.activeform, or why did you expect it to hold a form reference, if the form didn't show up at all? Or did this just start by changing the DO FORM?

In what current directory are you? If in exe mode this will not matter, as the scx is compiled into the exe, but in IDE mode of course that matter to find the form at all.

Another thing that's bad: If the syncer.scx error method is your only error handler, you will only get errors after the form loaded successfully. Create a main prg and start genreal error handling early on to catch all errors and have at least a messagebox of them, if not a log.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top