有没有人尝试将delphi附加到Windows Server 2008 64位下的自己的Windows服务(32位应用程序)进程中?
当我尝试这样做时,我收到错误: 无法创建流程。参数不正确。
如果你们中的任何一个人知道如何做到这一点,那将非常感谢你的帮助。
谢谢!
答案 0 :(得分:10)
虽然您可以调试Delphi服务,但您需要跳过许多环节才能使其正常运行。我从不打扰并只是确保我的服务既可以作为服务运行,也可以作为标准应用程序运行。当我想调试时,我作为标准应用程序运行,因此避免了所有的麻烦。
为了这个答案的目的,我已经将所有代码整理成一个文件,但是你想要以不同的方式构建它。
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.
要使用此功能,您需要创建一个继承自TMyService
的新类,并实现Initialise
和CreateRunner
。 CreateRunner
是关键。在我的服务中,这会创建一个对象,该对象又会打开一个侦听套接字,以供客户端进行通信。
标准应用代码非常基本。它甚至没有终止机制 - 它在while True
循环内运行。这与我的调试需求无关。
答案 1 :(得分:1)
您是否尝试以管理员身份运行IDE?
我已经在Win64下完成了这样的进程附加,但据我记忆,我必须以管理员权限运行IDE。