The console application is installed as a service
I'm looking for and trying to install a console app as a service, but haven't figured out how to do it.
any recommendation?
in fact i just wanted to install as a service and start automatically every time windows start or delay start
program Project1;
Uses
Windows,
SysUtils,
Dialogs,
Messages,TlHelp32,Classes, Graphics, Controls, SvcMgr,ExtCtrls;
Const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
type
TService1 = class(TService)
private
public
function GetServiceController: TServiceController; override;
end;
var
Service1: TService1;
Msg: TMsg;
Procedure ServiceController(CtrlCode: DWord); stdcall;
begin
Service1.Controller(CtrlCode);
end;
Function TService1.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
Function IsAdmin: Boolean;
var
hAccessToken: THandle;
ptgGroups: PTokenGroups;
dwInfoBufferSize: DWORD;
psidAdministrators: PSID;
x: Integer;
bSuccess: BOOL;
begin
Result := False;
bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
hAccessToken);
if not bSuccess then
begin
if GetLastError = ERROR_NO_TOKEN then
bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
hAccessToken);
end;
if bSuccess then
begin
GetMem(ptgGroups, 1024);
bSuccess := GetTokenInformation(hAccessToken, TokenGroups,
ptgGroups, 1024, dwInfoBufferSize);
CloseHandle(hAccessToken);
if bSuccess then
begin
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, psidAdministrators);
{$R-}
for x := 0 to ptgGroups.GroupCount - 1 do
if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
begin
Result := True;
Break;
end;
{$R+}
FreeSid(psidAdministrators);
end;
FreeMem(ptgGroups);
end;
end;
begin
if IsAdmin then
begin
// Install me as service
end else
begin
ShowMessage('Not Running As Admin');
end;
while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.
source to share
There are at least two ways: one is the "correct" way and one is the "wrong" (but works).
The wrong way to work
You can run any application as a utility (host), for example:
- ServiceEx , "a free Windows application that allows a regular program to run as a Windows service." I've never used this, I just found it through googling.
- One of the two utilities Microsoft provides (since this is from MS, I would use this one.)
Why is it wrong? Because if you want your application to run as a service, you must create a service application. And it just so happens that it's very easy with Delphi. This is the correct way:
Correct way: create a service application
This delphi.about.com article has a lot of information about service applications . However, it is quite simple: create a new service application via File> New> [possibly Other>] Service Application. Set the display name, etc. To install it, run it using the command line /install
; to remove with /uninstall
.
If the reason your command line application runs as a service is because you don't want to write two applications, with good design you can minimize the extra work. There are two applications in your project group, your command line application and your service application. Then pass the code in other files - for example, write the code to make your application once, and include / call it from both projects.
source to share
The TService requires a TServiceApplication to build and run it, just like a TForm needs TApplication to build and run it.
Application.Initialize;
Application.CreateForm(TService1, TService1);
Application.Run;
Due to an issue with TServiceApplication, this is no longer a console application.
As far as I know, if you really want to write a console service, you need to skip TService and use almost the windows API to achieve Console service.
There is an old example on the internet with an explanation: NT Service and Console Application
Quoting from this article:
Delphi compiler support for developing NT services using TServiceApplication and TService classes. But Delphi's approach does not support dual interface and is very overhead. I am showing how to write a lightweight application to work with two interfaces using the Windows API function. Even the sample application is written in Delphi, it is very easy to port it to another compiler because only native API functions are used.
I would say making Delphi TServiceApplication is much easier ...
source to share