?
Solved

Service application, main window, logoff problem

Posted on 2005-03-13
15
Medium Priority
?
967 Views
Last Modified: 2008-03-03
I have an application which should run as a regular server application (with some very little user interface -- settings dialog, log window), but -- optionally -- as well as a system service on a 2003 Server (in this case teh user interface may not be visible).

As modifying the application into a system service seems to be much too difficult, I made a small system service application which launches my application on system startup. This way the program is already running when the CTRL+ALT+DEL logon screen appears, and is able to serve the network clients. The settings dialog and the log window aren't available in this mode, but that doesn't really matters (and I may solve that later).

The problem is that if I log on and then off from an account, the application is stopped by the system (even if it runs as a system owned application rather than a user owned one, and it was running before the user logged on).

My questions are:
1. Does this happen because my application has a main window, or because it isn't a regular system service (just a system owned application, started by a system service)?
2. Do I have any chance to solve this problem without transforming the application into a regular system service?
3. In case I will have to transform it into a system service: my application uses the message queuing system of the Windows (some incoming client messages are queued as Windows messages, sent by PostMessage to the handle of a window); will this work if it will become a system service? If so, what window handle will I have to send the message to?

Waiting for suggestions,
Adam
0
Comment
Question by:biroadam
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
15 Comments
 
LVL 46

Expert Comment

by:aikimark
ID: 13531320
1. because it isn't a system service
2. depending on what it does, you might place the application program into the All Users start-up directory or add an entry in the Run registry key.
3. I don't know the reference, but there is a way to have a form handle associated with a service.  Maybe someone else already knows this.
0
 
LVL 46

Expert Comment

by:aikimark
ID: 13531484
3...I asked someone who's done this and they issued a CreateHandle function/method.  His service could receive Windows messages.

He described the process of creating and debugging a service.  He bases his services on a DataModule.  It is an easy thing to drop into and provides a decent debugging environment.  He then wraps the data module in code that issues the same commands as the service will receive (Start, Stop, Restart, etc.).  After he has debugged this code, he removes his wrapper and points the PC's services manager to the compiled datamodule.

Also, there are some commercial products that provide a means to migrate a windowed application into a service.
0
 

Author Comment

by:biroadam
ID: 13532467
Hi aikimark,

Thank you for the comments.

1. Are you very sure that only the system services aren't stopped on user logoff? This stopping story seems to me a little bit weird: on an NT server, there are a lot of programs running simultaneously, and if somebody logs off, it won't stop all the other programs, except the services.

2. That wouldn't help at all, as my main problem was that on user logoff the application stops. Starting it again on next logon wouldn't be a big improvement.

3. Could you point a little more exactly a commercial product that could help to migrate a windowed application into a service?

Adam
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 46

Expert Comment

by:aikimark
ID: 13533719
Adam,

1. Some services are set to start automatically and some manually.  You might be observing services that are manual.

Services are supposed to be available when the system starts, not just when someone is logged on.  If you observe a service stops when a user logs off, I would look at the properties of the service.  Also, I'd like to know how you are measuring the existence of the service when you are not logged on.

2. That is why I qualified my comment by the work that needs to be done by the program.

3. In no particular order:
http://delphi.icm.edu.pl/ftp/d20free/vpcsrvce.zip

From http://www.latiumsoftware.com/en/pascal/0030.php
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running an application as an NT Service
=======================================

In Windows NT/2000, one option is executing your application with
SRVANY.EXE so it runs as a service, but the application won't benefit
from all the features the OS makes available for services. SRVANY.EXE
is basically for Win 9x service applications that you want to run as
services in NT.

If you want your application to truly be an NT service, you should
design it as such (File menu / New... / New / Service Application).
Here you can find some examples:

  http://www.aldyn.ru/demos/
  http://delphi.icm.edu.pl/ftp/d50free/svcxmpl.zip
  http://delphi.icm.edu.pl/ftp/d40free/servicew.zip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

http://www.delphi32.com/vcl/3655

http://www.delphi3000.com/articles/article_3379.asp

For .Net environments (requires D8/D2005)
http://cc.borland.com/codecentral/ccweb.exe/listing?id=20795

http://www.activeplus.com/us/products/smillcontrol/

http://www.online-admin.com/howtozone/service_register.html
0
 

Author Comment

by:biroadam
ID: 13534037
Hi aikimark,

I have the feeling that you misunderstood my question (1). You were saying that the application is closed on user logoff because -- I quote --  "it isn't a system service". This is what I'm not very sure about, and I think the answer is a little more complex.

Here is a trivial but quite relevant example: if user A logs on and starts an application, then user B also logs on (without user A being logged off) and then logs off, the application started by user A obviously won't be stopped. With other words, not ALL the non-service applications are closed on a user logoff.
I think it would be logical that only the processed owned by user B to be closed when user B logs off -- however, it seems that also system owned processes (such as my application) are closed. My question is: exactly what and why are closed on a user logoff.

After making some more tests, I start to have the feeling the problem is caused indeed by the fact that the application has a main window, rather than by the fact that it isn't a system service. I've made a small application which has a visible main form, and beeps periodically. This application is started by the system service, so it starts to beep when the CTRL+ALT+DEL logon screen appears.
The interesting part is that the main window will appear on the screen of the first user who logs in -- doesn't matter which one. So either I log in as user A or user B, the window of the system owned application will appear on my screen, and then on logoff it will be closed. And apparently this is what directly causes the stopping of the application.

My newest idea is that maybe I should create the main window explicitly in a special user account (created specially for the application, so wouldn't be supposed to log on), let's say account C, and then maybe it would not be closed when user A or user B logs off. I'll start to check this idea in the next few hours.

But of course not before reading the links listed by you.

Thank you,
Adam
0
 
LVL 46

Expert Comment

by:aikimark
ID: 13534328
<<user B also logs on (without user A being logged off) >>
1. How is user B logging on?

As far as I know, the process of one user logging on automatically logs the prior user off.

I think I was trying to find some scenario where a service might be started by one user and be stopped when that user logged off.  Certainly if the first user starts a non-WinService application program, it should be stopped when the first user is logged off.

===========================
I will rephrase my core workaround question...
What does this application program do for each user and for the system?
0
 
LVL 10

Expert Comment

by:_Katka_
ID: 13536848
Hi, as far as I know it doesn't depend on
being service or not but being executed
under SYSTEM "user". There're four types:

LOCAL SERVICES
NETWORK SERVICES
SYSTEM
LOGGED USER(S)

first three are not stopped when user is logged
off. So you have to pass your application as a
system one or any type of system service. This
can be done by executing them with parameter:

SVCHOST.EXE -k

regards,
Kate
0
 

Author Comment

by:biroadam
ID: 13537141
Hi aikimark,

First, the answer for your question:
This is a RIP (Raster Image Processor) software, used in the pre-press industry. It is doing many things, such as:
- driving imagesetters, platesetters, inkjet printers,
- serving PC client applications through a TCP port; the real visual interface is on these client applications, which normally run on workstations,
- the newest feature I am working on at the moment is that it also serves Macs (unfortunately 90% of the pre-press workstations are still Macs) through the Remote Desktop interface; the Mac users will log on from the Mac version of the Remote Desktop Client software; the client application of our RIP software will start automatically in full screen mode, with a Mac XP theme, so hopefully the Mac user will have the feeling that is working with a regular Mac client application. If the software runs on a 2003 Server, several Mac clients will be able to connect to the server simultaneously (while the XP can serve only one visual interface at once, i.e. a remote desktop user OR a local user), each one having its own screen.

On the other hand, the RIP must be able to run as regular application too (this will be the way 90% of our customers will use it), with some system tray icons and some setting dialogs -- this is one of the reasons I really don't want to transform it into a system service.

If it runs on a 2003 Server, it will have already to be launched when the CTRL+ALT+DEL logon screen appears (otherwise user intervention would be needed when the printing equipment is powered on, which would be very uncomfortable), but it shouldn't be stopped under no circumstances, except the shutdown of the PC. So the RIP will have to run whatever would happen on the PC -- users logging on and off, etc.

> How is user B logging on?
> As far as I know, the process of one user logging on automatically logs the prior user off.

The NT servers can serve several clients simultaneously; using Remote Desktop, several clients can be logged on at the same time, from different accounts or from the same account.

About my idea: it seems that it is working, though there are a few things to sort out. Here is what I do:
1. I create a user account which will be exclusively used for running the application (no user will log on and especially off from that account),
2. My system service application uses the LogonUser API function, getting a token for that user account,
3. Then starts the application with the CreateProcessAsUser function.
4. The application will run then in that user account, and won't be bothered by users loggin on and off.

There is one problem though: if this application has a visible window, it will mess up the display of the currently logged on user. So all the windows of the application have to be hidden, otherwise it won't work well.

Adam
0
 

Author Comment

by:biroadam
ID: 13537179
Hi Katka,

My application was running in the SYSTEM account (that's because it was started by a system service), but it was stopped on user logoff. So I'm afraid your theory doesn't work.

Adam
0
 
LVL 46

Expert Comment

by:aikimark
ID: 13538060
Here's a simplification:

Create a service from scratch.  The purpose of the service is to ensure that your application program is running.  It wakes up every 10 seconds and looks for the program.  If not there, it starts the program.  You don't really have to convert your program to a service, just make sure it's running.

======================
What do you do when the PC goes into power-save mode?

If this is such an important application, I would recommend placing the constantly running copy on a server that NO user can get to.  "USER" is a four-letter word.
0
 

Author Comment

by:biroadam
ID: 13542060
Hi aikimark,

1.

> Create a service from scratch.  The purpose of the service is to ensure that your application program is running.  
> It wakes up every 10 seconds and looks for the program.  If not there, it starts the program.  You don't really
> have to convert your program to a service, just make sure it's running.

This is what the freeware XYNTService application does (http://www.codeproject.com/system/xyntservice.asp), and I don't really understand how this approach could be useful. In my particular case, letting the application to stop and then restarting it in a few seconds would mean:
- the currently processed jobs will be all aborted and lost,
- the printings will be aborted, and the imagesetter, platesetter or inkjet printer would stop during the printing (maybe needing user intervention to abort the page and enter to a ready state),
- all the clients will be disconnected, etc.

If I think of other possible service applications (audio, video, client/service applications, etc.), stopping the server application is almost always at least unconfortable, if not fatal.

2.

> What do you do when the PC goes into power-save mode?

Power-save modes usually are set to wake up when there is some kind of activity on the PC. For sure a PC which will run as a server will have to be configured to not lose its main role, i.e. serving the clients anytime.

3.

> If this is such an important application, I would recommend placing the constantly running copy on
> a server that NO user can get to.  

I am rather protecting the customer from an unwanted stop of the server than from malicious user intervention. If a user wants to stop the application, can do it in many ways -- the easiest one would be shutting down the server. My problem was that simply logging on and then off is probably the most likely thing which will happen to that server, so it would be very unprofessional and definitely against of the user's wish if the application would stop in such circumstances.

4.

> "USER" is a four-letter word.

Sorry, I'm probably too tired to understand what did you mean by that.

5.

I'm not sure whether you understood this, but I DID FIND A WORKING SOLUTION for my problem. If the 'Run as NT service' option is checked, the application will create an user account (something like ServiceAccountOfMyApplication, eventually protected by a password so that a user cannot log on not even by mistake), and then my small service application will start the main application in this account (using the LogonUser and CreateProcessAsUser API functions). This way the application will run exactly like a service, without being bothered by user logons and logoffs.

6.

If you -- or somebody else -- could offer a solution which doesn't involve the creation of an extra user account (which I find a little unprofessional), but in the same time offers real system service functionality (i.e. not stopping on user logoff), I'd be very glad.

So the question is still open.

Regards,
Adam
0
 

Author Comment

by:biroadam
ID: 13562677
Hi everybody,

Here is the really good solution I've found on the web: http://www.torry.net/vcl/system/nt/wmservice.zip
This is a sample Delphi code showing how to make a windows application to act both as a system service and as a regular application, depending on the way it is started.

The working principle is the following:

1. There is a function, CiaStartService, which detects whether the application has been started as a system service or not. A call to this function has to be placed at the very beginning of the application source, before the TApplication and the application windows have been created. (It also detects whether the service has to be installed or uninstalled by the command line switches -- I took this off, as I had special needs, and used the CreateService API call instead.)

2. If this function says that the application isn't running as service, TApplication and the windows have to be built in the old way,

3. However, if the function says that the application is running as service, the windows will be built using CiaService.CreateWindow instead of Application.CreateWindow, and then the application will be started using CiaService.Run instead of Application.Run.

4. Finally, in the application closer event handlers (typically the one of the Exit menu item) another small change is needed: if the application is running as a service, a message has to be posted to the service thread instead of closing the main window. In order to do this in an elegant way (in the sample code, this was done directly in the close event handler), I've added a StopService method to the TCiaService class which does this.

In conclusion, these changes can be done by (1) adding the uCiaServiceTools.pas unit to the application, (2) introducing an IF statement to the application's startup code, and in the service branch, copying the window creation sequence and slightly modifying it (basically replacing Application with CiaService), (3) changing the close event handler.

This is a 10 minutes procedure, and after that, the application will be a service and a regular application in the same time. I highly recommend it to everybody (though I admit, I had to make quite a lot of changes for my special needs).

Regards,
Adam
0
 
LVL 46

Expert Comment

by:aikimark
ID: 13564686
Adam,

Great Torry link.  I'm surprised I didn't find it during my prior search.

The "USER" comment was a joke.  4-letter-words are synonymous with foul (vulgar) language words in American English.  "USER" also has four letters and users are often the cause of much trouble for software developers and often evoke foul language after an encounter with a user.

I'm glad you found a solution.
0
 

Accepted Solution

by:
PAQ_Man earned 0 total points
ID: 15132106
PAQed with points refunded (500)

PAQ_Man
Community Support Moderator
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question