Alternative to Application.DelayInitialize for Delphi 7 Service? - delphi

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.

Related

Running Service Continuously - Delphi

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.

restart service in case of exception

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.

How to stop a Delphi 6 COM server application re-registering with COM at startup

I have a set of legacy Delphi 6 aplications that are out of process COM servers. In attempting to run these programs as a normal domain user on Windows I see them when running up (without any command line arguments or switches) attempting to update chunks of HKEY_CURRENT_CLASSES. this fails due to lac of permission to the HKCR hive. It appears that the act of running a Delphi 6 COM server causes it to attempt to register its embedded COM types with the system registry.
I do not want this behavior normally. We would do this once during install under and adminatrative account to initalise the COM registry, but would not want to do this under normal running conditions of a non adminastrative account. (if you moniroy the system with sys internals process monitor you can see the failed registry key access attempts).
Is there a command line switch I can pass to a Delphi 6 COM server to prevent this automatic COM registrtion logic?
I don't think you're actually seeing what you think you are...
Delphi only tries to install COM servers if they haven't already been installed. I suspect what you're seeing is your application checking to see if it's registered yet or not. The reason you're seeing the failures is because back in Delphi 6 the registry key would have been opened with ALL_ACCESS rights (D6 was prior to XP/Vista/Win7), and I think that's what's causing your failed registry access attempts.
In answer to your question, though: No, there's no command line switch to prevent the automatic registration logic.
It will always try to register the server from TComServer.Initialize unless the startup parameter is /UNREGSERVER which will remove the registry settings. If the startup parameter is /REGSERVER you will get an exception if the registration failed otherwise it will just swallow the exception. Automatic registration of out-proc COM servers has been removed in later version of Delphi. The only option you have to remove this behavior in Delphi 6 is to modify TComServer.Inititalize to only register the server when FStartMode is smRegServer or smUnregServer.

Is it possible to run a hidden console application from a Windows service?

I've written a server in Delphi 2010 that needs to launch a console application every now and again to back up a database. The console application can send log information to the console window, but it is not required.
This works fine when running as an application, but when run as a service I get an access violation when launching the console application. This is the case even if I launch it hidden (SW_HIDE).
Is it possible to launch a hidden console application from a Windows service? The solution needs to work on XP, Vista and Windows 7.
EDIT: The access violation happens when I call ShellExecute.
If you are using ShellExecute, then don't: it won't work inside a service, and is almost never the best way to start a process.
Use CreateProcess in stead.
See this bunch of ShellExecute / CreateProcess question threads on stackoverflow.
--jeroen

Delphi datasnap with Apache

Has anyone ever managed to get a datasnap system (BDS2006) running in apache?
I have set up my apache to acceot cinnections to the httpsvr.dll as per this article
http://www.distribucon.com/blog/HTTPSRVRWithApache.aspx
.
My TWebConnection objects connects perfectly but as soon as my clientDataset becomes active I get an error saying "cannot load library/dll"
I assume it is a problem loading the com server into memory? Any Ideas?
(I am trying to get away without having to change my com server, so that i can use it on both IIS and apache installations.
If your application is using clientdataset, it also needs midas.dll.
You should deploy midas.dll or your application uses block should contain midaslib unit.

Resources