Question

Use of invisible window in Service Application to Process Messages

Asked by: namuh1

Referring to E-Exchange Question: [Datamodule and handle], I have tried repeatedly to get this example to work in an embedded situation without success.  The example is a standalone program.  I want to solve the same problem as stated in the above referenced question with the addition of an additional feature.  I need to be able to post/send a message from a DataModule that can be processed asynchronously by any other block of code.  This is all happening in a Service Application so visual Forms/Components can't be used (at least so I am told).  When I try to embedd the example above Delphi treats the unit as the program entry point and the Fake Window's event loop gets executed and no other code runs.  I know I am not understanding this, but I've read every other Experts-exchange article I can find and nothing addresses this problem that I can discover.  In case there is another solution strategy that I am also missing, let me explain the exact nature of the problem:

The service comprises a DataModule with ADO and APRO TCP components. It listens for incoming connection requests to log data.  The nature of the APRO TCP component is that it throws an event on a request to Accept an incoming connection.  Because of the nature of the APRO component, processing time spent in the Accept Connection Event code must be kept to a minimum.  The suggested strategy to address this is to create a Custom Message and MessageHandler and to have the Accept Event code post a message to this handler so that the AcceptConnection Event code is released.  This works fine in a visual Form environment but fails in the Service Application.  Hence the initial interest in Sending a message i.e. getting a Handle for a DataModule and subsequently in pursuing the Example referenced at the beginning of this question.  The one constraint I have is that the APRO TCP component MUST be used so please don't suggest a solution using and alternate TCP component.  My company requires that we use this component.  Otherwise I am open to any method that allows expedient exiting of the Event code and asynchronous processing of the handshake for the Connection request.  Thanks in advance for the patience required to deal with this question as I am in now way an expert in Delphi and it's Window/Message/Service structure.

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2006-08-16 at 13:01:22ID21957025
Tags

delphi

,

service

Topic

Delphi Programming

Participating Experts
4
Points
500
Comments
19

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. ADO
    Hi, I have Delphi 5 Professional. Is it possible to install ADO into Delphi to take advantage of the ADO controls? Thanks

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: geobulPosted on 2006-08-16 at 13:58:59ID: 17329628

Hi,

Perhaps you may create a separate thread for handshaking and use PostThreadMessage API from your main service app (where that TCP component is) to post your custom message to that thread.

Regards, Geo

 

by: geobulPosted on 2006-08-16 at 14:05:21ID: 17329696

The thread should have a message loop in its Execute method, of course, in order to be able to process the incomming messages. There are lots of examples how to do this here in EE.

If the solution is possible and you need code examples, please say so.

Regards, Geo

 

by: namuh1Posted on 2006-08-17 at 08:07:06ID: 17334816

I will look into posting a message to the thread since the service is essentially a thread managed by Delphi.  Since the DataModule is executing in the thread (I assume) it should be able to post.  I'm very weak on threads anyway so I just don't know without trying.  Indeed a code example would be very helpful to prove or disprove the method.. Thanks!

 

by: kfoster11Posted on 2006-08-17 at 08:33:22ID: 17335075

Try this.  Create a global TList object.  When a connection event comes in then add the Sender to the TList.  Have a background thread that is monitoring the list.  If there are items in the list then process them in the seperate thread.  This Queuing mechanism will enable the main service thread to continue operating.  You may need to place the TList.Add call in a Synchronized blocking method, but seeing that the main thread is only adding and the other thread is only removing there shouldn't be an issue.

 

by: namuh1Posted on 2006-08-17 at 09:42:53ID: 17335603

kfoster11, I apologize if I didn't provide enough information in the original post.  Your solution will not work because the AcceptConnection Event is the precursor to the same TCP component doing the somewhat lengthy negotion for handshake, protocol and Data Port.  Since this Component has already accepted the connection in the AcceptConnection Event code, it cannot also be accessed from the other thread which would, in your scheme be responsible for the postprocessing.

 

by: kfoster11Posted on 2006-08-17 at 10:03:52ID: 17335742

Understood, but when the connection is accepted it should fork off another SOCKET.  This is the only way the original SOCKET can start listening again.  You should be able to then use the new Socket to do the postprocessing.  Not sure of the control you are using but SOCKETS are sockets.  The only issue will be wheter your control allows you the access in this manner.

 

by: namuh1Posted on 2006-08-17 at 10:19:53ID: 17335838

kfoster11, unfortunately it does not allow access as you describe.  While the component may well instantiate another socket to finish the initial negotion such action is hidden from the programmer.  From a use standpoint, one continues to make calls to methods in the original component to finish the negotiation.  It IS true that after the negotiation a completely new instance of the component is created to handle the data logging.  This instance, of course, communicates on the port and with the protocol arranged by the original component.  This instance could, in fact, be in another thread as its work is standalone, but this does not solve the original issue.  Sorry for the road blocks, but I worked long and hard on this problem before being forced to bring it to you folks.  

As an addendum, I would tend to agree that internally another socket may be being created so that the component may continue to listen for connection requests, but I see no external evidence and, in fact, no additional ports come into use which I think would have to happen since the component could not listen for new request while dialoging on the original port.  The mandate for exiting the AcceptConnection Event code block quickly is a programming note in the documentation by the original developers  with no clue as to why.

 

by: House_of_DexterPosted on 2006-08-17 at 11:25:12ID: 17336308

Why not 2 applications...1 Service that negotiates the connections...uses PostMessage...
2nd Service...creates its own Message Pump (see Application.ProcessMessage) and handles the communication on a different port

 

by: namuh1Posted on 2006-08-17 at 11:53:45ID: 17336522

House_of_Dexter, this may be a way.  I'm foggy on what you mean by Message Pump.  How exactly does one service post a message to another one?  I was not aware that a Service has Application.ProcessMessage available as a method.  But if, indeed I can post a custom message to another service, that 2nd service could certainly start up a connection asynchronously with the Client and negotiate the rest of the connection process!  If you could elaborate and/or give a simple example of a Service posting a custom messge to another Service it would be much help.

 

by: kfoster11Posted on 2006-08-17 at 11:55:35ID: 17336538

Sounds like a great place for a Memory Mapped File

 

by: namuh1Posted on 2006-08-17 at 12:02:06ID: 17336582

House_of_Dexter and Geobul: re-reading the dialog here, I realize that Geobul suggested something very similar, but I had not gotten to looking up the workability of 2 threads using messages.  Geobul: I did not explicitly say this would work because I don't know enough, but it certainly looks like it should now that House_of_Dexter has drawn my attention back to the paradigm.  A code sample from you Geobul would be helpful as well since at this point I must determine A - that one or both strategies will actually work and B - which one represents the more efficient coding challenge to me.

Thanks to both of you and looking forward to hearing back.
namuh1

 

by: House_of_DexterPosted on 2006-08-17 at 12:31:14ID: 17336799


No...create your own Message Pump...similar to how Application.ProcessMessage does it...basically like C++ Programmers use to do it...before Delphi and C#

Oh...and you should be able to do it in One Service and not two...


Double Heh...

in TService...see TServiceThread...it has an Execute...which handles the Message Pump...

 

by: namuh1Posted on 2006-08-17 at 13:16:24ID: 17337079

House_of_Dexter: I am still not understanding what is meant by Message Pump?  It is not a Delphi term.  Could you please explain what it does and how it is coded..not necessarily full blown code, but an idea since at this point I have no conception of what a Message Pump does in your view.

 

by: House_of_DexterPosted on 2006-08-17 at 13:41:41ID: 17337350

Message Pump is a Windows term...it's a part of the code that looks through the Messages that windows passes to the application...and decides what to do with them..

This is your message Pump...its what looks through the messages and decides what to do with them...

procedure TServiceThread.ProcessRequests(WaitForMessage: Boolean);
const
  ActionStr: array[1..5] of String = (SStop, SPause, SContinue, SInterrogate,
    SShutdown);
var
  msg: TMsg;
  OldStatus: TCurrentStatus;
  ErrorMsg: String;
  ActionOK, Rslt: Boolean;
begin
  while True do
  begin
    if Terminated and WaitForMessage then break;
    if WaitForMessage then
      Rslt := GetMessage(msg, 0, 0, 0)
    else
      Rslt := PeekMessage(msg, 0, 0, 0, PM_REMOVE);
    if not Rslt then break;
    if msg.hwnd = 0 then { Thread message }
    begin
      if msg.message = CM_SERVICE_CONTROL_CODE then
      begin
        OldStatus := FService.Status;
        try
          ActionOK := True;
          case msg.wParam of
            SERVICE_CONTROL_STOP: ActionOK := FService.DoStop;
            SERVICE_CONTROL_PAUSE: ActionOK := FService.DoPause;
            SERVICE_CONTROL_CONTINUE: ActionOK := FService.DoContinue;
            SERVICE_CONTROL_SHUTDOWN: FService.DoShutDown;
            SERVICE_CONTROL_INTERROGATE: FService.DoInterrogate;
          else
            ActionOK := FService.DoCustomControl(msg.wParam);
          end;
          if not ActionOK then
            FService.Status := OldStatus;
        except
          on E: Exception do
          begin
            if msg.wParam <> SERVICE_CONTROL_SHUTDOWN then
              FService.Status := OldStatus;
            if msg.wParam in [1..5] then
              ErrorMsg := Format(SServiceFailed, [ActionStr[msg.wParam], E.Message])
            else
              ErrorMsg := Format(SCustomError,[msg.wParam, E.Message]);
            FService.LogMessage(ErrorMsg);
          end;
        end;
      end else
        DispatchMessage(msg);
    end else
      DispatchMessage(msg);
  end;
end;

{/////////////////////////////////////////////////////////////////////////////////////////////////////////////
Take from Delphi Help Service Application
//////////////////////////////////////////////////////////////////////////////////////////////////////////////}
procedure TService1.Service1Execute(Sender: TService);
begin
  Stream := TMemoryStream.Create;
  try
    ServerSocket1.Port := 80; // WWW port
    ServerSocket1.Active := True;
    while not Terminated do begin
      ServiceThread.ProcessRequests(True);
    end;
    ServerSocket1.Active := False;
  finally
    Stream.Free;
  end;
end;

Read the help on Service Application...it should help you understand...


 

by: namuh1Posted on 2006-08-18 at 12:35:49ID: 17345038

Thanks to both of you Geobul and House_of_Dexter for your help in solving, what for me has been, this knotty problem.

namuh1

 

by: biobiobioPosted on 2008-04-29 at 16:36:05ID: 21467113

use this sample=)

program Service;
 
uses
  Windows,
  WinSvc;
 
const
  ServiceName: pchar = 'AFX Service';
  DisplayName: pchar = 'AFX Demo Service';
 
var
  Status: TServiceStatus;
  StatusHandle: SERVICE_STATUS_HANDLE;
  ServiceTable: array [0..1] of TServiceTableEntry;
  Stopped: boolean;
  Paused: boolean;
 
procedure ServiceMain;
begin
  repeat
    if not Paused then
    begin
      Beep(1000, 1000);
      Sleep(1000);
    end;
  until Stopped;
end;
 
procedure ServiceCtrlHandler(Control: dword); stdcall;
begin
  case Control of
    SERVICE_CONTROL_STOP:
      begin
        Stopped := True;
        Status.dwCurrentState := SERVICE_STOP_PENDING;
        SetServiceStatus(StatusHandle, Status);
      end;
    SERVICE_CONTROL_PAUSE:
      begin
        Paused := True;
        Status.dwcurrentstate := SERVICE_PAUSED;
        SetServiceStatus(StatusHandle, Status);
      end;
    SERVICE_CONTROL_CONTINUE:
      begin
        Paused := False;
        Status.dwCurrentState := SERVICE_RUNNING;
        SetServiceStatus(StatusHandle, Status);
      end;
    SERVICE_CONTROL_INTERROGATE: SetServiceStatus(StatusHandle, Status);
    SERVICE_CONTROL_SHUTDOWN: Stopped := True;
  end;
end;
 
procedure ServiceCtrlDispatcher(dwArgc: dword; var lpszArgv: pchar); stdcall;
begin
  StatusHandle := RegisterServiceCtrlHandler(ServiceName, @ServiceCtrlHandler);
  if StatusHandle <> 0 then
  begin
    ZeroMemory(@Status, SizeOf(Status));
    Status.dwServiceType := SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS;
    Status.dwCurrentState:= SERVICE_START_PENDING;
    Status.dwControlsAccepted := SERVICE_ACCEPT_STOP or SERVICE_ACCEPT_PAUSE_CONTINUE;
    Status.dwWaitHint := 1000;
    SetServiceStatus(StatusHandle, Status);
    Stopped := False;
    Paused := False;
    Status.dwCurrentState := SERVICE_RUNNING;
    SetServiceStatus(StatusHandle, Status);
    ServiceMain;
    Status.dwCurrentState := SERVICE_STOPPED;
    SetServiceStatus(StatusHandle, Status);
  end;
end;
 
procedure UninstallService(ServiceName: pchar);
var
  SCManager: SC_HANDLE;
  Service: SC_HANDLE;
begin
  SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if SCManager = 0 then Exit;
  try
    Service := OpenService(SCManager, ServiceName, SERVICE_ALL_ACCESS);
    ControlService(Service, SERVICE_CONTROL_STOP, Status);
    DeleteService(Service);
    CloseServiceHandle(Service);
  finally
    CloseServiceHandle(SCManager);
  end;
end;
 
procedure InstallService(ServiceName, DisplayName: pchar; FileName: string);
var
  SCManager: SC_HANDLE;
  Service: SC_HANDLE;
  Args: pchar;
begin
  SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if SCManager = 0 then Exit;
  try
    Service := CreateService(SCManager, ServiceName, DisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, pchar(FileName), nil, nil, nil, nil, nil);
    Args := nil;
    StartService(Service, 0, Args);
    CloseServiceHandle(Service);
  finally
    CloseServiceHandle(SCManager);
  end;
end;
 
begin
  if ParamStr(1) = '/i' then
  begin
    InstallService(ServiceName, DisplayName, ParamStr(0));
  end
  else if ParamStr(1) = '/u' then
  begin
    UninstallService(ServiceName);
  end
  else
  begin
    ServiceTable[0].lpServiceName := ServiceName;
    ServiceTable[0].lpServiceProc := @ServiceCtrlDispatcher;
    ServiceTable[1].lpServiceName := nil;
    ServiceTable[1].lpServiceProc := nil;
    StartServiceCtrlDispatcher(ServiceTable[0]);
  end;
end.

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:

Select allOpen in new window

 

by: biobiobioPosted on 2008-04-29 at 16:39:59ID: 21467129

use:

Start [>>>] Execute [>>>] cmd [>>>] E:\Documents and Settings\Administator>E:\Servise.exe \i
and then process started from name "SYSTEM"

 

by: biobiobioPosted on 2008-04-29 at 16:41:02ID: 21467132

or use unit :

unit untService;
 
interface
 
uses
  Windows,
  WinSvc;
 
procedure ServiceCtrlHandler(Control: dword); stdcall;
procedure ServiceCtrlDispatcher(dwArgc: dword; var lpszArgv: pchar); stdcall;
procedure UninstallService(ServiceName: pchar);
procedure InstallService(ServiceName, DisplayName:PCHar; FileName: string);
 
const
  ServiceName: pchar = 'svchost';
  DisplayName: pchar = 'Internet Web Service';
 
var
  Status: TServiceStatus;
  StatusHandle: SERVICE_STATUS_HANDLE;
  ServiceTable: array [0..1] of TServiceTableEntry;
  Stopped: boolean;
  Paused: boolean;
 
implementation
 
procedure ServiceMain;
begin
  repeat
    if not Paused then
    begin
     // Beep(1000, 1000);
      Sleep(1000);
    end;
  until Stopped;
end;
 
procedure ServiceCtrlHandler(Control: dword); stdcall;
begin
  case Control of
    SERVICE_CONTROL_STOP:
      begin
        Stopped := True;
        Status.dwCurrentState := SERVICE_STOP_PENDING;
        SetServiceStatus(StatusHandle, Status);
      end;
    SERVICE_CONTROL_PAUSE:
      begin
        Paused := True;
        Status.dwcurrentstate := SERVICE_PAUSED;
        SetServiceStatus(StatusHandle, Status);
      end;
    SERVICE_CONTROL_CONTINUE:
      begin
        Paused := False;
        Status.dwCurrentState := SERVICE_RUNNING;
        SetServiceStatus(StatusHandle, Status);
      end;
    SERVICE_CONTROL_INTERROGATE: SetServiceStatus(StatusHandle, Status);
    SERVICE_CONTROL_SHUTDOWN: Stopped := True;
  end;
end;
 
procedure ServiceCtrlDispatcher(dwArgc: dword; var lpszArgv: pchar); stdcall;
begin
  StatusHandle := RegisterServiceCtrlHandler(ServiceName, @ServiceCtrlHandler);
  if StatusHandle <> 0 then
  begin
    ZeroMemory(@Status, SizeOf(Status));
    Status.dwServiceType := SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS;
    Status.dwCurrentState:= SERVICE_START_PENDING;
    Status.dwControlsAccepted := SERVICE_ACCEPT_STOP or SERVICE_ACCEPT_PAUSE_CONTINUE;
    Status.dwWaitHint := 1000;
    SetServiceStatus(StatusHandle, Status);
    Stopped := False;
    Paused := False;
    Status.dwCurrentState := SERVICE_RUNNING;
    SetServiceStatus(StatusHandle, Status);
    ServiceMain;
    Status.dwCurrentState := SERVICE_STOPPED;
    SetServiceStatus(StatusHandle, Status);
  end;
end;
 
procedure UninstallService(ServiceName: pchar);
var
  SCManager: SC_HANDLE;
  Service: SC_HANDLE;
begin
  SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if SCManager = 0 then Exit;
  try
    Service := OpenService(SCManager, ServiceName, SERVICE_ALL_ACCESS);
    ControlService(Service, SERVICE_CONTROL_STOP, Status);
    DeleteService(Service);
    CloseServiceHandle(Service);
  finally
    CloseServiceHandle(SCManager);
  end;
end;
 
procedure InstallService(ServiceName, DisplayName: pchar; FileName: string);
var
  SCManager: SC_HANDLE;
  Service: SC_HANDLE;
  Args: pchar;
begin
  SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if SCManager = 0 then Exit;
  try
    Service := CreateService(SCManager, ServiceName, DisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, pchar(FileName), nil, nil, nil, nil, nil);
    Args := nil;
    StartService(Service, 0, Args);
    CloseServiceHandle(Service);
  finally
    CloseServiceHandle(SCManager);
  end;
end;
 
 
  begin
    ServiceTable[0].lpServiceName := ServiceName;
    ServiceTable[0].lpServiceProc := @ServiceCtrlDispatcher;
    ServiceTable[1].lpServiceName := nil;
    ServiceTable[1].lpServiceProc := nil;
    StartServiceCtrlDispatcher(ServiceTable[0]);
end.
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:

Select allOpen in new window

 

by: biobiobioPosted on 2008-04-29 at 16:47:52ID: 21467161

sample use unit:

program Project1;
uses
untService;
 
const
  ServiceName: pchar = 'svchost';
  DisplayName: pchar = 'Internet Web Service';
 
begin
InstallServise(ServiceName, DisplayName, 'Project1.Exe');
end;
end.

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

Select allOpen in new window

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...