Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2014-02

Invalid standard handles in Windows service mode?

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

MegaBrutal

Hi all,

I have a Windows service application, and recently I noticed it doesn't work if I compile it with FPC 2.6.2. It can be started in user mode too, and in that case I didn't find any problem - at first I was really puzzled what might be the reason. With some cumbersome debugging, I found the application crashes when it tries to write to the standard output.

Right, writing to the standard output when the application has been started by the service manager is kind of useless because the output won't be seen anywhere. But still, it just worked until this point. When the program is started from the console, the output is seen; and when it is started as a service, who cares?

I wonder, however, why does the FP runtime library initializes the application differently than it does when the app is started from console? I have an {$APPTYPE CONSOLE} directive in my program, so Free Pascal should believe it's a console application. Older FP runtimes didn't have this problem. I actually wonder, how does the runtime ever gets to know whether the program is started on console or as service? (This is an interesting question for me, because even I can only determine whether the program is running as a service when I try to call StartServiceCtrlDispatcher - if that fails, my application believe's it's running on the console. I wonder if there is a more effective way that FP runtime is using.)

To be clear: the very same source compiled with FPC 2.6.0 works on the very same OS, while compiled with FPC 2.6.2 the application crashes. So I suspect the problem is not that Windows wouldn't make stdout accessible in service mode, or stuff like that.

If I need to check whether I can use stdout before using it, so be it, but still I'd like to know the background of this issue. Along the way, maybe I find a better way to check for service mode. Anyway, how can I check if I have a valid stdout handle before actually trying to write to it?

MegaBrutal

Reply by email

Michael Van Canneyt
to MegaBrutal
MegaBrutal wrote 12 lines
Hi all, I have a Windows service application, and recently I noticed it doesn't work if I compile it with FPC 2.6.2. It can be started in user mode too, and in that case I didn't find any problem - at first I was really puzzled what might be the reason. With some cumbersome debugging, I found the application crashes when it tries to write to the standard output. Right, writing to the standard output when the application has been started by the service manager is kind of useless because the output won't be seen anywhere. But still, it just worked until this point. When the program is started from the console, the output is seen; and when it is started as a service, who cares? I wonder, however, why does the FP runtime library initializes the application differently than it does when the app is started from console?

It does not. The FP runtime has no idea about service apps or not. The same binary can run as regular or as service application.

Show quoted text 5 lines
I have an {$APPTYPE CONSOLE} directive in my program, so Free Pascal should believe it's a console application. Older FP runtimes didn't have this problem. I actually wonder, how does the runtime ever gets to know whether the program is started on console or as service? (This is an interesting question for me, because even I can only determine whether the program is running as a service when I try to call StartServiceCtrlDispatcher - if that fails, my application believe's it's running on the console. I wonder if there is a more effective way that FP runtime is using.)

Well, to my knowledge, the runtime does not try to check whether it is a service or not.

To be clear: the very same source compiled with FPC 2.6.0 works on the very same OS, while compiled with FPC 2.6.2 the application crashes. So I suspect the problem is not that Windows wouldn't make stdout accessible in service mode, or stuff like that.

No, it may be that the stdout routines simply check better what they are doing, and report errors correctly.

If I need to check whether I can use stdout before using it, so be it, but still I'd like to know the background of this issue. Along the way, maybe I find a better way to check for service mode. Anyway, how can I check if I have a valid stdout handle before actually trying to write to it?

You can check the handle of the StdOutputHandle variable. if it is invalid (-1), you don't have output.

Michael.

Reply by email

MegaBrutal
to Michael Van Canneyt

2014-02-21 10:18 GMT+01:00 Michael Van Canneyt :

You can check the handle of the StdOutputHandle variable. if it is invalid (-1), you don't have output.

Thanks for your reply, it helped a lot! StdOutputHandle is 24 when I start the program on the console, and 0 when it starts as a service. Which means, StdOutputHandle doesn't get initialized in service mode! I don't know why is this - the older runtimes didn't have this problem. It's present since 2.6.2.

Reply by email

Michael Van Canneyt
to MegaBrutal
MegaBrutal wrote 8 lines
2014-02-21 10:18 GMT+01:00 Michael Van Canneyt : You can check the handle of the StdOutputHandle variable. if it is invalid (-1), you don't have output. Thanks for your reply, it helped a lot! StdOutputHandle is 24 when I start the program on the console, and 0 when it starts as a service. Which means, StdOutputHandle doesn't get initialized in service mode! I don't know why is this - the older runtimes didn't have this problem. It's present since 2.6.2.

It does not necessarily mean this.
It can also mean that windows returns 0 as StdOutputHandle if the service manager has started the program, depending on how the program was compiled (GUI or console app).

2.6.0 has been released in 2012.
The code that sets up stdin/out/etc hasn't changed at least since 2008-09-10 (and probably way before that). and it is executed unconditionally.

Once more:
The RTL itself does no checks to see whether a program is a service or not, only whether the APPTYPE is console or GUI.

So maybe the IsConsole behaviour has changed.

Michael.

Reply by email