delphi 7 on 64 bit server 2008, problem
Has anyone ever tried to a开发者_运维知识库ttach delphi to his own windows service(32 bit app.) process under Windows Server 2008 64 bit?
When I try to do this I get the error: Unable to create the process. The parameter is incorrect.
if anyone of you know how to do this, that help would be really appreciated.
Thanks!
Whilst you can debug a Delphi service there are a number of hoops that you need to jump through to make it work. I never bother and simply ensure that my services can run either as a service or as a standard app. When I want to debug I run as a standard app and so sidestep all the headaches.
I've hacked out all the code into a single file for the purpose of this answer, but you'd want to structure it a bit differently.
program MyService;
uses
SysUtils, Classes, Windows, Forms, SvcMgr;
type
TMyService = class(TService)
private
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
procedure ServicePause(Sender: TService; var Paused: Boolean);
procedure ServiceExecute(Sender: TService);
procedure ServiceContinue(Sender: TService; var Continued: Boolean);
protected
FDescription: string;
FEventLogSourceName: string;
procedure Initialise; virtual; abstract;
class function CreateRunner: TObject; virtual; abstract;
public
constructor Create(AOwner: TComponent); override;
function GetServiceController: TServiceController; override;
end;
TMyServiceClass = class of TMyService;
{ TMyService }
constructor TMyService.Create(AOwner: TComponent);
begin
inherited;
Initialise;
OnStart := ServiceStart;
OnStop := ServiceStop;
OnPause := ServicePause;
OnExecute := ServiceExecute;
OnContinue := ServiceContinue;
end;
procedure TMyService.ServiceStart(Sender: TService; var Started: Boolean);
begin
Started := True;
end;
procedure TMyService.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
Stopped := True;
end;
procedure TMyService.ServiceContinue(Sender: TService; var Continued: Boolean);
begin
ServiceStart(Sender, Continued);
end;
procedure TMyService.ServicePause(Sender: TService; var Paused: Boolean);
begin
ServiceStop(Sender, Paused);
end;
procedure TMyService.ServiceExecute(Sender: TService);
var
Runner: TObject;
begin
Runner := CreateRunner;
Try
while not Terminated do begin
ServiceThread.ProcessRequests(True);
end;
Finally
FreeAndNil(Runner);
End;
end;
var
Service: TMyService;
procedure ServiceController(CtrlCode: DWORD); stdcall;
begin
Service.Controller(CtrlCode);
end;
function TMyService.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure RunAsService(ServiceClass: TMyServiceClass; var Service);
var
Application: TServiceApplication;
begin
Application := SvcMgr.Application;
Application.Initialize;
Application.CreateForm(ServiceClass, Service);
Application.Run;
end;
procedure RunAsStandardExecutable(ServiceClass: TMyServiceClass);
var
Application: TApplication;
Runner: TObject;
begin
Application := Forms.Application;
Application.Initialize;
Runner := ServiceClass.CreateRunner;
Try
while True do begin
Try
Application.HandleMessage;
Except
Application.HandleException(Application);
End;
end;
Finally
FreeAndNil(Runner);
End;
end;
procedure ServiceMain(ServiceClass: TMyServiceClass);
begin
if FindCmdLineSwitch('RunAsApp', ['-', '/'], True) then begin
RunAsStandardExecutable(ServiceClass);
end else begin
RunAsService(ServiceClass, Service);
end;
end;
begin
ServiceMain(TMyService);
end.
To use this you need to create a new class, inherited from TMyService
, and implement Initialise
and CreateRunner
. CreateRunner
is the key. In my services this creates an object which in turn opens a listening socket ready for clients to communicate over.
The standard app code is pretty basic. It doesn't even have a mechanism to terminate—it runs inside a while True
loop. That doesn't matter for my debugging needs.
Did you try running the IDE as Administrator?
I've already done such process attach under Win64, but I had to run the IDE with Administrator rights, as far as I remember.
精彩评论