Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

NT service

Posted on 1999-07-26
25
Medium Priority
?
317 Views
Last Modified: 2013-12-03
I have created an NT service/app hybrid.  When starting up the service, I get a timeout error (running in Win2000 Pro):

Microsoft Management Console gives an error of:

Error 1053: The service did not respond to the start or control request in a timely fashion.

What does this mean, specifically, and where do I look in my code to correct it?

I also get a system log error: Timeout (30000 milliseconds) waiting for service to connect.  (Before the above error).  However, it is not 30 seconds but close to 5 seconds.

Thanks,

Don
0
Comment
Question by:dmetzler
[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
  • 13
  • 11
25 Comments
 
LVL 7

Expert Comment

by:leflon
ID: 1403772
is your service running so you get the error?
i had a service which did a lot of initializing, so the service control manager states a timeout error. but when i checked the running services "net start" th e service was runnig ok.
after i moved the init code the service starts ok.
maybe u got the same problem.
your app ids starting ok?
0
 

Author Comment

by:dmetzler
ID: 1403773
No - the service does not get to run - it stops with an error.  It looks like the SERVICE_ALL_ACCESS changes this so it will run, but then it exits almost immediately.

How do I keep my service running until it gets a stop request?

Thanks!

Don
0
 
LVL 86

Expert Comment

by:jkr
ID: 1403774
What code are you using in your 'ServiceMain()' function? Are you reporting 'SERVICE_RUNNING' to the SCM correctly?
0
Free learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

 

Author Comment

by:dmetzler
ID: 1403775

>>
What code are you using in your 'ServiceMain()' function? Are you reporting 'SERVICE_RUNNING' to the SCM correctly?
>>

I think so, but I will check.

Also - does the ServiceMain() function run in a new thread?  If so, how can I call methods in the main CWinApp derived application?

Thanks!

Son
0
 

Author Comment

by:dmetzler
ID: 1403776

>> 
What code are you using in your 'ServiceMain()' function? Are you reporting 'SERVICE_RUNNING' to the SCM correctly?
>> 

Yes - this is being done.  Then I sit in a loop until a flag is set to let me know to exit the service/application.  It seems I will need to handle the main app msg queue checking here - yes?

Thanks,

Don (not Son)

0
 
LVL 86

Expert Comment

by:jkr
ID: 1403777
Hmm - could you post the code?
0
 

Author Comment

by:dmetzler
ID: 1403778

Essentially, it looks like this (some things are missing, but I have included the ServiceMain routine from the CASService class):

void CMyApp::InitInstance()
{
   if (bService)
   {
       StartNTService();
   }
}

void CMyApp::StartNTService()
{
   CASService  service;
}

void CASService::ServiceMain()
{
   RegisterCtrlHandler();

   m_bStopped = FALSE;

   ReportStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0, 1, 0);
   Sleep(500);
   ReportStatusToSCM(SERVICE_RUNNING, NO_ERROR, 0, 1, 0);

   // sit in a tight-loop until we're ready to exit
   while (!m_bStopped)
   {
      theApp.CheckStatus();
   }
}



0
 
LVL 86

Expert Comment

by:jkr
ID: 1403779
Could you post the code for 'CheckStatus()' also?
0
 

Author Comment

by:dmetzler
ID: 1403780
It's pretty simple - it current checks memory and disk drive space - nothing complicated.

Don

0
 
LVL 86

Expert Comment

by:jkr
ID: 1403781
Have you considered something like this (a loop seems to be a bit inappropriate to me):

void    SocketServerStartup ()
{
    HANDLE  hEvent;

    hEvent  =   CreateEvent (   NULL,   FALSE,  FALSE,  TEXT    (   OBJECT_NAME));

    if  (       ERROR_ALREADY_EXISTS    ==  GetLastError    ()
            ||  ERROR_SUCCESS           ==  GetLastError    ()
        )
        {
            HANDLE  hThread;
            DWORD   dwTID;

            hThread =   CreateThread    (   NULL,
                                            0,
                                            CommThread,
                                            NULL,
                                            0,
                                            &dwTID
                                            );

            DBGTRACE   (   L"SocketServerStartup():\twaiting for stop event...\n");

            ReportStatusToSCMgr (   SERVICE_RUNNING,
                                    g_dwErr,
                                    0
                                );


            WaitForSingleObject (   hEvent, INFINITE);

            DBGTRACE   (   L"SocketServerStartup():\treceived stop event...\n");

            return;
        }
}

void    ServiceStop (   void)
{
    HANDLE  hEvent;

    ReportStatusToSCMgr (   SERVICE_STOP_PENDING,  
                            NO_ERROR,
                            1000
                        );
    hEvent  =   CreateEvent (   NULL,   FALSE,  FALSE,  TEXT    (   OBJECT_NAME));

    if  (   ERROR_ALREADY_EXISTS    ==  GetLastError    ())
        {
            DBGTRACE   (   L"HPSUDServiceStop():\tsetting event...\n");

            SetEvent    (   hEvent);
        }

    Sleep   (   500);

    ReportStatusToSCMgr (   SERVICE_STOPPED,
                            NO_ERROR,
                            0
                        );

}

VOID WINAPI     ServiceCtrl (   DWORD   dwCtrlCode)
{
    //  Handle the requested control code.
    switch  (   dwCtrlCode)
            {
                //  stop service.
                case SERVICE_CONTROL_STOP:

                    ServiceStop ();
                    return;

                //  update the service status.
                case SERVICE_CONTROL_INTERROGATE:
                    break;

                //  invalid control code
                default:
                    break;

            }

    ReportStatusToSCMgr (   g_ssStatus.dwCurrentState,  NO_ERROR,   0);

}



0
 

Author Comment

by:dmetzler
ID: 1403782
Using an event seems to be a better way.  I will implement this.

However, my real concern is the call to theApp.CheckStatus().  Is this reference still valid now that my service is running in a new thread?  What happens to the original thread for the CWinApp derived class?

I understand about 90% of what is happening, but need to get over the last 10%.

Thanks!

Don
0
 
LVL 86

Expert Comment

by:jkr
ID: 1403783
>>Is this reference still valid now that my service is running
>>in a new thread? 

It is (assuming that it is global), but if you're about to use several threads, you'll have to protect the access to it ...
0
 

Author Comment

by:dmetzler
ID: 1403784

>>
It is (assuming that it is global), but if you're about to use several threads, you'll have to protect the access to it ...
>>

Like with a CSingleLock?

Yes - I am doing that.

The odd thing is that after the CWinApp starts and calls the thread functions, the tray icon installed by the CWinApp disappears, as if the main app thread has exited.

Don
0
 
LVL 86

Expert Comment

by:jkr
ID: 1403785
>>The odd thing is that after the CWinApp starts and calls
>>the thread functions, the tray icon installed by the
>>CWinApp disappears

That's not odd at all - you'll have to use a message pump to process the callback messages from the system tray icon, otherwise it'll lead the system to remove the icon...
0
 

Author Comment

by:dmetzler
ID: 1403786
>>
That's not odd at all - you'll have to use a message pump to process the callback messages from the system tray icon, otherwise it'll lead the system to remove the icon...
>>

I did not know that, but that you.

One other thing - my service name is the same as the display name.  Would this be a problem?


0
 
LVL 86

Expert Comment

by:jkr
ID: 1403787
No, this usually isn't a problem (though that maybe your service name is is a bit less 'illustrating' than the display name ;-)


0
 

Author Comment

by:dmetzler
ID: 1403788
Okay - I have my service functions communicating with the SCM successfully.  However, now I need to get the main CWinApp thread to complete and process.  It seems when the service code starts, the main app thread is suspended.  When the service stops, then the main app continues.

Is there a good way to handle this, perhaps by having my service code start at the end of the CWinApp::InitInstance() or perhaps via callback message?

Is there anyway to have both processes/threads running concurrently, but started from the same entry point?

Thanks,

Don
0
 
LVL 86

Expert Comment

by:jkr
ID: 1403789
Hmm, this is getting weird ;-)

So, you're mixing an MFC app with an NT service?

This IS possible, but I wouldn't recomment it (MFC performance resons...) - it'd be a good idea to separate maintaining the shell tray icon from the actual service code, e.g. by starting an application using the 'Run' registry entry (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run) and have it communicate with the service ( BTW, that's the way the McAfee Scanner communicates with it's SysTray Icon). The main reson for this concept is that a service does not necessarily have access rights to the currently logged-on user's window station ('LocalSystem' _usually_ has, but not necessarily).

(Err, I wrote a service that _can_ do this, but the code isn't available even for 50k points - but I know at least 10 MS URLs where they state that this is not possible... just showing off, sorry ;-)

It'll be difficult to start both a CWinApp and a service from the same entry point, as the assumptions/expections that both SCM and MFC make/have are a bit opposite - I've never tried it...
0
 

Author Comment

by:dmetzler
ID: 1403790
>>
Hmm, this is getting weird ;-)
>>

I like the more obscure programming challenges.  ;-)

>>
So, you're mixing an MFC app with an NT service?
>>

Yes. What if I ignore the tray icon for the service and then start a separate thread for the service, thus allowing the main app to run appropriately?

>>
...e.g. by starting an application using the 'Run' registry entry (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run) and have it communicate with the service ( BTW, that's the way the McAfee Scanner communicates with it's SysTray Icon). The main reson for this concept is that a service does not necessarily have access rights to the currently logged-on user's window station ('LocalSystem' _usually_ has, but not necessarily).
>>

Is this valid for NT too?

>>
(Err, I wrote a service that _can_ do this, but the code isn't available even for 50k points - but I know at least 10 MS URLs where they state that this is not possible... just showing off, sorry ;-)
>>

So how did you do it - can you share the basic idea?

>>
It'll be difficult to start both a CWinApp and a service from the same entry point, as the assumptions/expections that both SCM and MFC make/have are a bit opposite - I've never tried it...
>>

I am close - I start the CWinApp, which kicks off another thread to start the service (which starts another thread to handle the SCM).  Sloppy perhaps, but I think I can do it.

Thanks for ALL your help.

Don
0
 
LVL 86

Expert Comment

by:jkr
ID: 1403791
>>Yes. What if I ignore the tray icon for the service and
>>then start a separate thread for the service, thus
>>allowing the main app to run appropriately?

Hmm, could work - i.e. one thread using a CWinApp, the other one calling 'StartServiceCtrlDispatcher()'

>>Is this valid for NT too?

Yes, definitely - I'm mainly using NT.

>>So how did you do it - can you share the basic idea?

The basic idea is to manipulate the access control lists for both the window station and the desktop ;-)



0
 

Author Comment

by:dmetzler
ID: 1403792
Thanks for all of your help!

Don
0
 
LVL 86

Accepted Solution

by:
jkr earned 1400 total points
ID: 1403793
Hmm, I take this as an invitation to 'answer' ;-)
0
 

Author Comment

by:dmetzler
ID: 1403794
Thanks for all of your help!
0
 
LVL 86

Expert Comment

by:jkr
ID: 1403795
Thanx a lot!!!

Regarding to tha fact that you raised the points, it seems that I indeed could help you, and that's a really good feedback ;-)

BTW: I'm glad that this Q moved to the PAQ section as I didn't take enough care when posting the code - there's still a reference to the customer (oops ;-)  ...
0
 

Author Comment

by:dmetzler
ID: 1403796
Thanks for the help!

Don
0

Featured Post

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

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

This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…

661 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