My service does not seem to continuously run.
procedure TService1.ServiceExecute(Sender: TService);
begin
While not Terminated do
ServiceThread.ProcessRequests(True);
end;
This is what I currently have that is suppose to be keeping the service running, but it does not do so.
This bit of code only runs when the service is started from the Windows Service Manager. Once you have your service .exe file, use a command prompt to start it with the /install command line argument, and use net start <your-service-name> or the Service Management dailog from the Administrative Tools from the Start Menu or Control Panel to start the service.
If you want to run the service in the Delphi debugger, start Delphi with administrative privileges and attach to the running process. But it's more advisable to have all logic in separate units, and have a separate version of the project as a 'plain exe' the run the project's procedures that you can run in the debugger.
The ServiceThread.ProcessRequests call is needed to allow the service manager requests to be processed (starting/pausing/stopping the service) but you don't call it yourself, nor should you override the TServiceThread instance. The default TServiceThread instance takes care of calling ProcessRequests and also calls the OnStart/OnStop etc handlers of your TService instance.
I normally create a thread in the TService instance OnStart event handler, and let that thread run the service function.
If the service manager stops your service after a short while, it is usually an indication that the ProcessRequests call isn't being called correctly or frequently enough.
Related
Is there an alternative to Application.DelayInitialize for Delphi 7? I'm trying to create a Delphi 7 Service that hosts a COM Server but it doesn't work and I believe it is because I'm not using Application.DelayInitialize.
Re: Windows Service / DelayInitialize
I have written several COM-hosting services using BCB6, and they all work fine in all Windows versions from Win9x onwards, so I have had to deal with this same issue many times.
Simply don't call Application.Initialize() at process startup on Win2003+, wait until the TService's OnStart or OnExecute event to call it. That way, the service API is running before any COM objects are initialized.
The trick is to delay the call to Application.Initialize() ONLY on Win2003+ and ONLY when the service is actually running. DO NOT delay the call if either:
The service is running on Windows versions earlier than 2003.
when the service is being (un)installed.
when the COM object is being (un)registered.
Under those conditions, call Application.Initialize() normally at process startup.
So, you will need to check the OS version and the command line parameters to know when to call Application.Initialize() correctly.
I am building a Windows service app using Delphi , RAD Studio 10
Upon my investigation I came across with a Eset Windows service which wonderfully was protecting itself from being Stopped or terminated.
On stopping the service using (windows service manager) or (end process button)
or (end task button) following error messages occurs :
The operation couldn't be completed.
access denied.
same thing is true with its registry keys . The error message is :
Can not delete info: Error while deleting key
I tested Administrator access and system access. in both cases i was not successful.
I want to build such self-defense mechanism for my own application protecting my service and registry key.
Any idea would be helpful.
Thank you for your time.
update :
I want to know how i can do it in Delphi ... that's why it is tagged Delphi
and If someone wants to stop the service or uninstall it ....
he or she can just use my own applications UI to do it.
edit 2 :
As Remko mentioned I thnk DACL and ACL is better way to handle it , I couldn't find any good reference for it. Is there any good reference for Delphi language?
Protecting from SCM stop is very easy. Assuming you are using TService, you can handle the TService.OnStop event and set its Stopped parameter to False. And assign an error code to the TService.ErrCode or TService.Win32ErrCode property.
Unless you are writing security software, you really should not protect from TaskManager termination. Admins should be allowed to kill misbehaving processes. That being said, you can use SetSecurityInfo() to assign a DACL to your service process that grants/denies access to particular users and/or groups as needed.
You can also use ChangeServiceConfig2() to configure your service's "failure actions" to restart the service if it terminates unexpectedly.
To protect your Registry key, you can use the lpSecurityAttributes parameter of RegCreateKeyEx(), or use the RegSetKeySecurity() function, to assign a SECURITY_DESCRIPTOR to your key that contains a DACL that grants/denies access to particular users and/or groups as needed.
I would like to create run a delphi service that create a Tform with a wordOcx that write a document, and thus far, I have no problems, but I would like that service to run the (word.exe) process in a specific user session.
thanks corchi
There is no way for the service to directly specify which user session an out-of-process COM object runs under. You would have to create a separate .exe file for the service to run, and have that .exe access WordOcx as needed, instead of accessing it inside the service directly. The service can then use CreateProcessAsUser() to run the .exe in a specific user session.
Whenever a specific Windows service fails I want to run a program I've created myself. However, I simply can't find a way to make it fail on purpose, so that I can actually test that everything works correctly.
Note that the service in question is not something I've written myself, so I can't make it fail programmatically from inside the code. I wouldn't, however, mind writing a program that can make a service fail.
Of course I would prefer just having a "Make service fail" button somewhere in services.msc ... ;)
The server I'm doing this on is running Windows Server 2012.
If you don't want to use command line :
As an admin open the Windows Task Manager, in the Services tab find the service you want to test. Right click the service and click on Go to process. The selected process (if any) is the one corresponding to your service. Kill this process to simulate a service failure.
Be aware that killing a process this way can lead to problems.
Define "fail". If you want the process to end, just use pskill or a similar tool that can terminate a process elevated (as an admin).
I'm developing service application that must restart itself. What are the ways of doing that? Is it possible to ask system start application again if it is stopped? I'm using Delphi 2007.
Your service can programably configure recovery options for itself by calling the Win32 API ChangeServiceConfig2() function inside of its AfterInstall event. Set the dwInfoLevel to SERVICE_CONFIG_FAILURE_ACTIONS and set the lpInfo to point at a SERVICE_FAILURE_ACTIONS record describing what you want to happen when the service fails.
If you go into services.msc you can configure this for you service. You don't have to do it in code. See the Recovery tab when you open the properties of you service.