Solved

Start NT service after installation

Posted on 2009-07-15
12
580 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
  • 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
 

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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

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…
When you start your Windows 10 PC and got an "Operating system not found" error or just saw  "Auto repair for startup". After a while, you have entered a loop for Auto repair which does not fix anything and you will be in a  panic as all your work w…
The viewer will learn how to successfully create a multiboot device using the SARDU utility on Windows 7. Start the SARDU utility: Change the image directory to wherever you store your ISOs, this will prevent you from having 2 copies of an ISO wit…
With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…

707 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now