Hallo!
Ich habe ein kleines Problem beim Zugriff auf einen
COM Server der innerhalb eines Services läuft. Hierzu kurz ein Überblick.
Ich habe einen Service über den Delphi Assistenten erstellt und dann die Typenbibliothek sowie ein Automatisierungsobjekt hinzugefügt. In diesem existiert nun eine Funktion, welche nur ganz simpel eine Debugmeldung ausgibt.
Delphi-Quellcode:
unit COM_MyServer;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
ComObj,
ActiveX, MyServerLib_TLB, StdVcl, Windows;
type
TMyServer =
class(TAutoObject, IMyServer)
protected
procedure TestServer;
safecall;
end;
implementation
uses ComServ;
{ TMyServer }
procedure TMyServer.TestServer;
begin
windows.OutputDebugString(PCHAR('
TMyServer.TestServer: erfolgreich ausgeführt'));
end;
initialization
TAutoObjectFactory.Create(ComServer, TMyServer, Class_MyServer,
ciMultiInstance, tmApartment);
end.
Der zugehörige Client sieht ganz einfach aus. Dieser importiert die TLB und greift dann auf den Server zu.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
MyServer:=CoMyServer.Create;
MyServer.TestServer();
end;
Denn nach der Erstellung des Services habe ich eine exe. Diese wird als erstes als Service installiert (Parameter /install) und anschließend die Typenbibliothek registiert (Parameter /RegServer).
Wenn man nun durch den Client darauf zugreifen will, dann erhält man das Problem, dass die exe einfach noch einmal unter dem gerade angemeldeten Benutzeraccount gestartet wird. Der
COM Server wird nicht mit dem laufenden Service assoziiert. Hier schaffte ein wenig googlen und die
MSDN Doku Abhilfe. Man muss den Service noch einmal anlegen und dann unter der CLASS
GUID als AppID (welche durch den /RegServer Befehl in die Registry gefügt wurden) eintragen.
Delphi-Quellcode:
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\MeinService.exe]
"AppID"="
{D3FEF3C6-5F1B-42DC-A9CB-246BD681CA2D}"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\
{D3FEF3C6-5F1B-42DC-A9CB-246BD681CA2D}]
@="MeinService"
"LocalService"="MeinService"
"ServiceParameters"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\
CLSID\
{CLASS GUID AUS DER TLB}]
"AppID"="
{D3FEF3C6-5F1B-42DC-A9CB-246BD681CA2D}"
Sobald dies drin ist versucht auch der Client nicht mehr den Service noch einmal unter dem UserMode zu starten. Wenn der Dienst nicht läuft dann wird er gestartet, wenn er läuft wird er nicht erneut gestartet. Also so wie es erwartet wird.
Jedoch habe ich nun ein neues Problem. Denn wenn der Client das MyServer:=CoMyServer.Create; ausführt, dann erhalte ich die Meldung "Zugriff verweigert". Muss man für den Zugriff auf
COM Server die innerhalb des Service Modes laufen noch irgendwelche Security Descriptoren beachten? Die
MSDN Doku ist hier eher etwas mau...
Meine bisherigen Quellen...
http://msdn.microsoft.com/en-us/library/ms809975.aspx
http://
msdn.microsoft.com/en-us/library/ms693774(VS.85).aspx