Solved

Start NT service after installation

Posted on 2009-07-15
12
589 Views
Last Modified: 2013-12-28
Hello experts.

I write a small test program as a Windows "NT" service. I can install / uninstall / start / stop  the service manually without problems and It behaves correctly.

Then I used installshield to do a setup program. I tried to make it start automatically after installation but gives an error of not enough permissions and I have to abort the installation process.

Then I changed the option to not start the service automatically after installation and when I try to start it manually, it does not start.  I also tried with advanced installer and get the same kind of error. I don´t know what could be wrong.

I don´t want to provide user/password because I want to install it in a network with mixed users (domain and out of domain). So for the users not in domain I will not know the user/password.

Any help will be be much appreciated.

Thank you.
0
Comment
Question by:arturosm
[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
  • 6
  • 5
12 Comments
 
LVL 2

Expert Comment

by:gtrifidis
ID: 24868670
In my opinion you have to check the following :

1) Is there a domain policy that forbits domain users to install service and or applications?
2) As far the non domain users if the account you are using has sufficient rights to install an application or service things should go fine.
3) You could create a batch file to start and stop your service e.g
 net start [yourservicename]
 net stop [yourservicename]
You can read more here
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/net_start.mspx?mfr=true
0
 
LVL 18

Expert Comment

by:Johnjces
ID: 24874249
What operating system?
0
 
LVL 18

Expert Comment

by:Johnjces
ID: 24874270
Woops...
... and are you wanting to start this service using InstallShield or Delphi. If INstallShield you might also check

http://community.installshield.com/

John
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:arturosm
ID: 24874703
Hi Johnjces,

The client machines will have mainly Windows XP and Vista.
0
 
LVL 18

Expert Comment

by:Johnjces
ID: 24874988
and what about how you want to start the service?
0
 
LVL 18

Accepted Solution

by:
Johnjces earned 500 total points
ID: 24875027
In any event here is some code you can use and modify to build a console application that you can call and run after the installation via InstallShield or from your program or whatever.

Note that this has what I call XPManifest as a resource which is a Vista manifest file requesting the program to run "asAdministrator".

John
program VistaCDLibSvcHelper;
 
{$APPTYPE CONSOLE}
 
{$R 'XPTheme.res' 'XPTheme.rc'} //remove if you do not make an XP/Vista manifest file
 
uses
  XPTheme, SysUtils, WinSvc, Windows;
 
procedure ProcessMessages;
var
  Msg: TMsg;
begin
  if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
end;
 
Procedure Delay(MSecs: Cardinal);
var
 FirstTick, CurrentTick : Cardinal;
 Done : Boolean;
begin
 Done := FALSE;
 FirstTick := GetTickCount;
 While Not Done do
  begin
   ProcessMessages;
   CurrentTick := GetTickCount;
   If Int64(CurrentTick) - Int64(FirstTick) < 0 Then
    begin
     If CurrentTick >= (Int64(FirstTick) - High(Cardinal) + MSecs) Then
      Done := TRUE;
       End
        Else
         If CurrentTick - FirstTick >= MSecs Then
          Done := TRUE;
  end;
end;
 
//******************************* start service ********************************
// return TRUE if successful
// sMachine: machine name, ie: \\SERVER
// empty = local machine
// sService:  service name, ie: Alerter
//******************************************************************************
function ServiceStart(sMachine, sService : string ) : boolean;
var
  schm,
  schs   : SC_Handle;
  ss     : TServiceStatus;
  psTemp : PChar;
  dwChkP : DWord;
  Count : Integer;
begin
  //ss.dwCurrentState := -1;  {This errored out as a constant in D5}
  Count := 0;
  schm := OpenSCManager(PChar(sMachine), Nil, SC_MANAGER_CONNECT);
  if(schm > 0) then
   begin
    schs := OpenService(schm, PChar(sService), SERVICE_START or SERVICE_QUERY_STATUS);
    if(schs > 0) then
    begin
      psTemp := Nil;
      if(StartService(schs, 0, psTemp)) then
      begin
        if(QueryServiceStatus(schs, ss)) then
        begin
          while(SERVICE_RUNNING <> ss.dwCurrentState)do
          begin
            dwChkP := ss.dwCheckPoint;
            Inc(Count);
            // Sleep(ss.dwWaitHint);
            delay(ss.dwWaitHint);
            if(not QueryServiceStatus(schs, ss)) then
            begin
             break;
            end;
             if (ss.dwCheckPoint < dwChkP) or (Count > 2) then    // added Count to ensure that the routine
              begin                                               // breaks if the service never starts
               break;
              end;
          end;
        end;
      end;
      CloseServiceHandle(schs);
    end;
    CloseServiceHandle(schm);
  end;
 // return TRUE if the service status is running
  Result := SERVICE_RUNNING = ss.dwCurrentState
{ If SERVICE_RUNNING = ss.dwCurrentState then
  Result := True
   else
    Result := False;  }
end;
 
//******************************** stop service ********************************
// return TRUE if successful
// sMachine: machine name, ie: \\SERVER
// empty = local machine
// sService:  service name, ie: Alerter
//******************************************************************************
function ServiceStop(sMachine, sService : string ) : boolean;
var
  schm,
  schs   : SC_Handle;
  ss     : TServiceStatus;
  dwChkP : DWord;
  Count : Integer;
begin
  Count := 0;
  schm := OpenSCManager(PChar(sMachine), Nil, SC_MANAGER_CONNECT);
  if(schm > 0) then
  begin
    schs := OpenService(schm, PChar(sService), SERVICE_STOP or SERVICE_QUERY_STATUS);
    if(schs > 0) then
    begin
      if(ControlService(schs, SERVICE_CONTROL_STOP, ss)) then
      begin
        if(QueryServiceStatus(schs, ss)) then
        begin
          while(SERVICE_STOPPED <> ss.dwCurrentState)do
          begin
            dwChkP := ss.dwCheckPoint;
            Inc(Count);
            // sleep(ss.dwWaitHint);
            delay(ss.dwWaitHint);
            if(not QueryServiceStatus(schs, ss)) then
            begin
              break;
            end;
            if(ss.dwCheckPoint < dwChkP) or (Count > 1000) then   // Added Count to ensure the routine
            begin                                                 // breaks if the service never stops.
              break;                                              // 100 was too low. 500 might be good.
            end;
          end;
        end;
      end;
      CloseServiceHandle(schs);
    end;
    CloseServiceHandle(schm);
  end;
  // return TRUE if the service status is stopped
  Result := SERVICE_STOPPED = ss.dwCurrentState
  {if SERVICE_STOPPED = ss.dwCurrentState then
   Result := True
    else
     Result := False;}
end;
// NOTE: My service name is "CDLibSvrSvc". This is NOT the exe name but the service name.
begin
 if ParamStr(1) <> '' then
  begin
   if ParamStr(1) = 'start' then
    begin
     if ServiceStart('', 'CDLibSvrSvc') then
      halt(1)
       else
        halt(0);
    end;
 
   if ParamStr(1) = 'stop' then
    begin
     if ServiceStop('', 'CDLibSvrSvc') then
      halt(1)
       else
        halt(0);
    end;
 
  end
   else
    halt(100);  // No Params...
end.

Open in new window

0
 

Author Comment

by:arturosm
ID: 24875156
Thanks, let me try it and I will be back maybe tomorrow.
0
 
LVL 18

Expert Comment

by:Johnjces
ID: 24875172
Good luck but do let us know. I am heading out of town (out of the country) and may not get back to you for some time should you ask me a direct question.

John
0
 

Author Comment

by:arturosm
ID: 24967665
Hello Johnjces and gtrifidis.

The solutions you provided serve to start and stop a service, that´s ok.

However, the problem I'm having is:

If I install my test service using Delphi (menu: Run/Parameters and use /INSTALL or /UNINSTALL) the service works well. Also if I install it using a command line Start/Run: myservice.exe /INSTALL or /UNINSTALL. In the above examples I have noted no entries are added to the registry. I can start and stop the service from the service manager and the service do it job correctly.

But If I use a MSI package generator such as Install Shield or Advanced Installer, an entry is added to the registry and when I try to start the service using code (Johnjces solution) or command line (gtrifidis solution) I got the 1053 error, "The service did not respond to the start or control request in a timely fashion". The same happens if I use the CreateService Windows API call from Delphi. In all these cases there is an entry added to the registry under services.

What could be the difference in the way delphi or a simple command line installs the service versus the way the API - MSI does it?

I have looked here for solutions to the 1053 error (Delphi), but they were force accepted in my opinion. So I did´t see a solution there.

I would like to use the API to create/start/stop the service because I would have more control if something goes wrong with the installation/functioning of my program. Maybe a second option is to study the error codes from the command line option. What do you think?

I'm using Windows XP in my development machine.

Kind regards.


0
 
LVL 18

Expert Comment

by:Johnjces
ID: 24970574
I cannot help you with an installer, and how they do stuff. Installing and starting a service in Delphi I can. However...

In order for a service to run well, entries in the registry should be made when the service is installed.

Make certain that in your service after install you have something like what's in the code snippet for good operation.

Good luck with your installer... just can't help you there!

John
procedure TCDLibSvrSvc.ServiceAfterInstall(Sender: TService);
var
 Reg : TRegistry;
begin
 NTEventLog.LogInfo('THE CD Library Server Service is installed', 0);
   Reg := TRegistry.Create(KEY_READ or KEY_WRITE);
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\' + Name, false) then
    begin
      Reg.WriteString('Description', 'Provides a Windows service allowing remote PC clients running THE CD Library! in client mode to control CD Carousels.');
      Reg.CloseKey;
    end;
  finally
    Reg.Free;
  end;
end;

Open in new window

0
 

Author Comment

by:arturosm
ID: 24984259
Hi Johnjces.

>I cannot help you with an installer, and how they do stuff. Installing and starting a service in Delphi I can.

In fact, at the end the problem was not the installer tool but the installation of my service which had something wrong but I don´t not exactly what. I start a new service project just to isolate the problem.

What worked was to leave the OnExecute event handler as simple as possible. I could realize the problem was the installation of my service and not the installer tools thanks to the code you provided in your first post regarding this solution.

Thank you again.

Mos.
0
 

Author Closing Comment

by:arturosm
ID: 31604129
Thanks for your help.
0

Featured Post

Create the perfect environment for any meeting

You might have a modern environment with all sorts of high-tech equipment, but what makes it worthwhile is how you seamlessly bring together the presentation with audio, video and lighting. The ATEN Control System provides integrated control and system automation.

Question has a verified solution.

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

If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
When you start your Windows 10 PC and got an "Operating system not found" error or just saw  "Auto repair for startup" or a blinking cursor with black screen. A loop for Auto repair will start but fix nothing.  You will be panic as there are no back…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Windows 8 comes with a dramatically different user interface known as Metro. Notably missing from the new interface is a Start button and Start Menu. Many users do not like it, much preferring the interface of earlier versions — Windows 7, Windows X…

756 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