Hallo,
Ich muss eine Service anwendung schreiben, in dem bestimmte Client Anwendung anforderung an ihm senden und die Bearbeitete daten zurück kommen.
Für's testen habe ich zwei normale Anwendungen geschrieben, in einem davon wird gleich in Constructor ein Thread ausgeführt. Zweite anwendunge sendet an den Thread mit PostThreadMessage daten und bekommt über dass gleichen weg ergebnis. Soweit läuft es auch.
Nun wenn ich gleche mit dem Service anwendung versuche, funktioniert es plötzlich nicht. Und zwar tut's nicht schon beim PostThreadMessage als Fehler bekomme ich (über GetLastError) ERROR_INVALID_THREAD_ID (1444). Wenn es gleiche aus TService mache, läuft's ja.
Kann mir jemand sagen was dran nicht stimmt !
[/delphi]
(Server)
Const
WM_BEEP = WM_USER + 100;
WM_INC = WM_USER + 101;
WM_INIT = WM_USER + 102;
type
TIDThread = Class (TThread)
Private
I : Integer;
Procedure WriteData;
Public
procedure Execute; override;
procedure WriteRegitry(ThreadID: Integer);
procedure Resume;
procedure Terminate;
End;
TIDService = class(TService)
procedure ServiceContinue(Sender: TService; var Continued: Boolean);
procedure ServicePause(Sender: TService; var Paused: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
procedure ServiceStart(Sender: TService; var Started: Boolean);
private
FThread : TIDThread;
public
{ Public-Deklarationen }
function GetServiceController: TServiceController; override;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
var
IDService: TIDService;
implementation
{$R *.DFM}
Uses
Registry, IniFiles, Forms;
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
IDService.Controller(CtrlCode);
end;
function TIDService.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure TIDService.ServiceStart(Sender: TService; var Started: Boolean);
begin
FThread.Resume;
PostThreadMessage(FThread.ThreadID , WM_INIT, 0, 0);
PostThreadMessage(FThread.ThreadID , WM_INC, 0, 0);
PostThreadMessage(FThread.ThreadID , WM_BEEP, 0, 0);
Started := True;
end;
procedure TIDService.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
FThread.Suspend;
Stopped := True;
end;
Constructor TIDService.Create(AOwner: TComponent);
Var Ini : TIniFile;
begin
Inherited;
FThread := TIDThread.Create(True);
Ini := TIniFile.Create('C:\Nora\TIDService.Ini');
Ini.WriteInteger ('Daten', 'SelfThread ', GetCurrentThreadID);
Ini.WriteInteger ('Daten', 'FThread', FThread.ThreadID);
Ini.Free;
end;
destructor TIDService.Destroy;
begin
FThread.Terminate;
FThread.WaitFor;
FThread.Free;
Inherited;
end;
procedure TIDService.ServicePause(Sender: TService; var Paused: Boolean);
begin
If Not FThread.Suspended Then FThread.Suspend;
Paused := True;
end;
procedure TIDService.ServiceContinue(Sender: TService; var Continued: Boolean);
Begin
If FThread.Suspended Then FThread.Resume;
// Hier lauft
PostThreadMessage(FThread.ThreadID , WM_INC, 0, 0);
PostThreadMessage(FThread.ThreadID , WM_BEEP, 0, 0);
Continued := True;
End;
{ TIDThread }
procedure TIDThread.Execute;
VAR
MSG : TMsg;
begin
WriteRegitry(-2{GetCurrentThreadID});
WHILE (NOT Terminated) DO BEGIN
IF (PeekMessage(Msg, 0, 0, 0, PM_Remove)) THEN BEGIN
TranslateMessage(Msg);
case Msg.message of
WM_BEEP:
WriteData;
WM_INC: Begin
Inc (I);
End;
WM_INIT : Begin
I := 0;
End;
ELSE
DispatchMessage(Msg);
end;
END // Message Verarbeitung
ELSE
Sleep(0); // CPU Zeit Freigeben, wenn keine Message vorliegt
END; // S
WriteRegitry(-1);
end;
Procedure TIDThread.WriteData;
Var Ini : TIniFile;
Begin
Ini := TIniFile.Create('C:\Nora\TestData.Ini');
Ini.WriteInteger ('Daten', 'I', I);
Ini.Free;
End;
procedure TIDThread.WriteRegitry(ThreadID: Integer);
Var R : TRegistry;
Ini : TIniFile;
begin
R := TRegistry.Create;
Try
If R.OpenKey('Software\NoRA\A_IDThread', True) Then Begin
R.WriteInteger('IDThread', ThreadID);
R.CloseKey;
End;
Finally
R.Free;
End;
Ini := TIniFile.Create('C:\Nora\Test.Ini');
Ini.WriteInteger ('Daten', 'ID', ThreadID);
Ini.WriteInteger ('Daten', 'SelfID', Self.ThreadID);
Ini.Free;
end;
procedure TIDThread.Resume;
Begin
Inherited;
WriteRegitry(GetCurrentThreadID);
End;
procedure TIDThread.Terminate;
Begin
Inherited;
WriteRegitry(0);
End;
[/code]
(Client)
procedure TForm2.Button2Click(Sender: TObject);
Var Error : Integer;
begin
SetLastError (0);
If Not PostThreadMessage(ThreadID, WM_BEEP, 0, 0) Then Begin
Error := GetLastError;
// Da läuft es immer wieder aufs Fehler
If Error = ERROR_INVALID_THREAD_ID Then Begin
ShowMessage ('Nicht OK : ERROR_INVALID_THREAD_ID');
Exit;
End;
ShowMessage ('Nicht OK : ' + IntToStr (Error));
End;
ShowMessage ('OK');
end;
[code]