Link to home
Start Free TrialLog in
Avatar of JustinWillis
JustinWillis

asked on

Need faster Service start, slower Service stop.

Hi, I have a service app for remote access, all works well, just need to fine tune it know hence this strange question.

Basically my remote apps starts as a service so I can see the Logon screen etc, then when windows restarts/shutsdown the service is obviously stopped, but my service seems to be the last one to run on startup, the logon prompt is on screen for ages before my service is started, is this because it was the last service to be installed? is there a way to trigger which order services are started in?? or does windows start them all at once so maybe it's just my app taking so long to initialize?

Hope that makes sense, the service is set to Automatic and is using local account with Interactive := true

I also want to try and delay the Stop command when windows is shutting down/restarting etc, again my service seems to be among the first to be stopped so I don't see much of the shutdown process remotely, hopefully this is connected again to a Service Stop order list somewhere, I want my service to be among the last to be stopped, maybe I can resist this for a while from within my service? although that would be an ugly way to solve the prob.

Thanks in advance for any help with this!

JustinWillis.
Avatar of JustinWillis
JustinWillis

ASKER

Obviously a tricky one, if it is even possible, i suspect it is as other remote control apps seem to have done it some how.

Upped the points.

Cheers,
JW.
ASKER CERTIFIED SOLUTION
Avatar of 2266180
2266180
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ok, was rather hoping for a hidden registry list somewhere or something with a start/stop order but you are probably right.

Delaying the stop sounds simple enough, I had already thought of that but was hoping for something a little more elegant, but hey, as long as it works right?

Starting will be trickier by the sound of it, yes I already have logging in place but not yet for startup timings, would not take long to implement, am already using threads for less important stuff, nothing that would effect performance but yes this could help too, will have to give it a try and post the results.

It currently takes about 40 seconds after I see the Logon dialogue before the service appears to be running.  If I run the exe normally it is up and running within 5 seconds, i suspect this service delay is caused mainly as so many other sevices are starting up at the same time, thus was hoping to be able to make mine a priority to windows.  I have about 7 forms created also, do you think it would also help to only create vital ones automatically and the rest when needed? this would be a pain to change but if it may help then.. would probably be a ticket to access violation city though :/

Thanks for the input, will let you know if it helps.

JustinWillis.
you could try to make the service start with highest priority and after load change it to normal priority and before stop change it to lowest priority.
another thing that you could do, is unsinstall the service, run a registry monitoring tool (from sysinternals for example) and then install the service. then check out the modified registry keys to see if you can tweak the order in which the services are started up.

depending on you application type, you should be able to determin the load time of each form using performance counters for example. in the dpr place before and after the createform a line to measure the time and the log it and you'll see if indeed there is a form that loads slowly. there is no reason to complicate things if forms load up fast (and I am not talking about loading at computer start, but when running the exe as you said when it loads in 5 sec)
also, if normally it takes around 5 seconds to load, then I don't think you can tweak it too much.
Yeah, if I run the service after startup it takes 4 seconds, same as simple launch of exe so probably not much I can do to speed this up on startup, takes 35 seconds during startup which is way too long, not vital, just annoying as other remote products which I won't mention allow you to connect before the logon dialogue has even popped up! that must be atleast 40 seconds faster load time, grrr, how on earth is that achieved??

Will try spying on the system to hopefully reveal the hidden location as you suggest, not sure why I did not think of that before, will let ya know, cheers.

JW.
Nope no sign of any hidden lists, watched the entire system but not much changed except the usual registry entries, the one thing that I am not too sure about and that was not recreated after uninstalling and installing again was this registry key...

HKEY_CURRENT_USER \ Software \ Microsoft \ Windows \ ShellNoRoam \ BagMRU \ 0 \ ....

Now within this key it gets rather complicated with a load of numbered keys within it, looks like a mess but one of them was created after service install, it seems to use values called "NodeSlot" and "NodeSlots", you can find this quickly by searching your registry for value "NodeSlot" with exact match.

Now the MRU seems familar, usually used in windows for keeping a list in a certain order is it not?? and curius that some NodeSlot's have a low number where as mine seems to have been assigned something line 186, which would make it neer the end of the list if it is indeed a list for services, maybe red herring but denitatly looks suspicious, what do you think??

Will try changing Priority on startup / shutdown to see what effect that has on timing.

Cheers,
JW.
a quick google on that:
http://support.microsoft.com/default.aspx?kbid=813711
also, keep in mind that system related info will never be kept in HKEY_CURRENT_USER for obvious reasons :)

what we (you :) ) are looking for should rezide under HKEY_LOCAL_MACHINE
yeah thought so, was just hoping it may lead to something i guess :P

ok, setting service to High priority in the OnStart shaved about 1 second off of the startup time, still about 34 seconds ;(

adding the following several times in the OnStop...

        sleep(1000);
        Application.ProcessMessages;

Does not seem to work either, neither does sleep(40000); any ideas on this? stopping it slower is less of a deal, starting quicker is the biggy, so far nothing has made much of a dent with this, well either really.

Also I used this in the service OnStart...

var
  H: THandle;
begin
  H := GetCurrentProcess();
  SetPriorityClass(H,HIGH_PRIORITY_CLASS);

is that the right place to use it you think? check Task manager afterwards and was set to High still, was just hoping that may help more than it has.
Must be a way to do this surely? my service starts quickly otherwise, windows is just picking on me ;(

JW.
Sorry, forgot to mention that if I stop the service manually it does indeed carry on working for another 40 seconds until it finally stops, which is exactly what I want, BUT when windows is restarted it seems to close in about 5 seconds, totally ignoring my sleep(40000); in the OnStop, again, windows is bullying me :/

Help! it's going out the window pretty soon! :P

Will close this soon if no one else has any other ideas, that being the case the points are yours ciuly.
I am sure my service is at the end of some damn startup list, my hard disk chunders for 30 secs after logon dialogue, (other services starting i guess), then last 4 seconds are mine, as soon as I see my service is started the hard disk stops chundering, which seems to indicate it is starting my service last, I was not expectig this, I assumed all was started at same time rather than going through them one by one, if it does start all at same time then why does it take 34 secs rather than 4? or is that just the way it goes?? annoying that other remote apps seem to start straight away.

Cheers,

JW.
hm... no, that is not the place to put it :)
setting high priority needs to be done when starting up and as soon as possible. so you need to put it in the oncreate event. besr place would be from where the service is launched, to att the priority to the parameter list (probably the registry, but I don't know here that is; maybe you have the location from the registry audit you have done earlier :) )

regarding the onstop ... hm. make your onexecute event similar to: (the delay part at least : )

procedure TService1.ServiceExecute(Sender: TService);
begin
[  initialize;]
  while not finished do
[   do something]
[  finalize;]
  put here the delays ;)
end;
you might consider redesigning the app to allow fast conenct possibility:
- start up and initiazlie the basic remoting first
- client can now connect
- start up and initialize the rest of the stuff

but this will take a lot of time.
Now got the following in ServiceExecute...

 while not Terminated do
 servicethread.ProcessRequests(true);
 sleep(60000);

again, this works fine when stopping the service manually, but when windows restarts it has none of it, just kills my service whether i have stuff to save or not???
something does not seem right here, have not changed much else, is a standard delphi service created through New | Service App...

Can't really see how I could improve speed by rejigging code, I know what you mean though, fast startup was a priority from the start of development, am I just expecting too much from the service part? is this long startup delay the norm? I am going to create another v simple service for testing purposes, will create one that posts timings to the event log and report back the results, not giving up without a fight :)

JW.
since you have a form, you could do an ugly thing like:
- catch the WM_Endsession message
- stop the restart
- wait a little
- initiate the stopped process (shutdown or restart)

stuff to help in detecting if restart or shutdown to initiate correct process:
https://www.experts-exchange.com/questions/20328666/Detecting-windows-shutdown.html
https://www.experts-exchange.com/questions/20598284/How-to-distinguish-Windows-SHUTDOWN-or-RESTART.html
https://www.experts-exchange.com/questions/21649005/Check-if-user-logout-or-shutdown.html
https://www.experts-exchange.com/questions/21019028/How-to-detect-the-difference-in-a-Logoff-Reboot-or-Shutdown.html?query=detect+shutdown+OR+reboot&topics=85
there was one in which I posted as well .. but I can't seem to find it anymore. it was using madhis components and one or more of the solutions above use it, so I guess it's ok
Thanks but not really what I need to do, the only reason I want to delay the service from stopping is so that the remote user sees as much as possible of the restart/shutdown so they can be pretty sure nothing else interupted it, if I interupt the restart/shutdown then there is no longer any point to my service staying active as there is nothing for the remote user to see of interest, and when I trigger the restart/shutdown again I am left with the same problem, do you see what I mean? I don't really have anything to save but windows doesn't know that does it? as far as it was conserned it forcefully stopped my service while still executing code in the OnExecute which is a bit odd.

Again other remote access programs show the screen right up to the end, somehow the service stays alive until the actual restart/shutdown happens.

What you say would most likely work but not what I need it for im afraid, will let you know shortly the result of new lighter service test.

JW.
hm. you are doing a "user" service. maybe there are "system" services that are executed first and stopped last. but I never heard of such thing. though possible. just another thing to check ;)
yep checked that already, tried setting startup type to Boot (which never auto starts, interesting), and system which fails as the execution path is set to something invalid.

OK, first apologies are in order, after creating another service that tries to do CTRL+ALT+DEL every 3 seconds on startup, i see this happen 4 seconds after I see the logon dialogue, sorry also to lovely windows for blaming it for the delay, obviously something is wrong somewhere with the main app, I guess a lot or trial and error is in order, will clear my schedule for the next few days :)

Will fall back to your original suggestion, logging the timings!! sorry, I was sure that my coding was not the cause, but you know what they say about assumption huh.  Sorry again to have wasted your time on this, will post my findings if I ever figure out what is causing such a large delay.

Cheers,
JW.
no problem, that is why we are here, to help :)

do post your findings as it may help others in the future ;)
Will do, some development to report actually, I did the same with my main app, as soon as it starts it tries to do CTRL+ALT+DEL, and guess what? within 2 seconds of seeing the logon dialogue it triggers!! so indeed the service is started pretty quickly, it seems then that the networking part or the forms take longer to create and get going as that is where my indy tcp components reside.  Again I think your initial timing logging will help in this regard, looks like I will be able to sort it quicker than expected if this is the case.

Going back to the slowing the stop, any idea why when I stop the service manually I hear 3 beeps every second before stopping with the below code...

OnStop Event...
        stopped := false;
        beep;
        sleep(1000);
        beep;
        sleep(1000);
        beep;
        sleep(1000);
        stopped := true;

and yet when choosing to restart windows I don't hear a single beep, niether is there any noticable delay? i'm sure I am doing that wrong too, should I try and get one of my forms to delay the service stop? doubt it, but what do I know..

Jw.
maybe the sound service already stopped? :) better then using beep and thing, use logging and log the time ;)
Mystery solved I think, basically my remote client app/service can be programmed (hard coded with another app) so it knows the where abouts of the server app on the net it should connect with, now when this is not stored (the case during previous testing) it simply uses whatever server app is available on the LAN (uses Indy UDP broadcast packet to locate a server app), still not sure what the delay is but now I know where to look and how to workaround for now, basically if the client has this stored info it works fine, kicks in as soon as logon dialogue appears which is great.

The app is designed to work without a stored server (incase you only want to use it on your lan) but is the reason behind the delay, will be looking at UDP code carefully, also this is a brief 2 way conversation so maybe the response from the server app is simply not getting back through to the client.

Anyway now I know the cause of delay will be possible to resolve it but now it is not such a big issue as if used properly it won’t do it anyway.  Thanks for your help, it led me to find the prob much quicker.

If anyone else does have this type of prob then please try logging times of things to find what is slowing it all down.

I found the following useful, it writes date&time to the windows event log..

var
    H: THandle;
    EventLog : Thandle;
    MyMsg:Array[0..2] Of PChar;
begin
  EventLog := RegisterEventSource(nil,PChar('JustRemoteIT Client'));
  MyMsg[0]:= pchar('Started at ' + datetostr(now) + ' ' + timetostr(now));
  ReportEvent(EventLog,EVENTLOG_INFORMATION_TYPE,0,1,nil,1,0,@MyMsg,nil);


I will keep working on a way to slow the service stopping on shutdown etc.

Cheers,
JustinWillis.