Autor |
Beitrag |
Raven280438
      
Beiträge: 99
|
Verfasst: Mo 11.08.14 10:09
Hi,
ich möchte einen Windows-Dienst programmieren, der (gesteuert durch ein anderes Programm) automatisch Netzlaufwerke verbindet und trennt.
Allerdings habe ich noch nie was mit Windows Diensten zutun gehabt.
Meine Frage: Windows Dienste laufen ja auch schon, wenn man noch nicht angemeldet ist. Ist es trotzdem möglich, Netzlaufwerke mit WNetAddConnection2A zu verbinden, oder gibt das Probleme.
Sind noch andere Probleme zu erwarten?
Gruß
|
|
jaenicke
      
Beiträge: 19326
Erhaltene Danke: 1749
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 11.08.14 10:34
Das funktioniert schon, aber ich hoffe dir ist klar, dass ein durch einen Dienst verbundenes Netzlaufwerk auch nur für den Benutzer verfügbar ist, unter dem der Benutzer läuft. Das ist in der Regel der Systembenutzer. Meldet sich dann ein anderer Benutzer an, sieht dieser das Netzlaufwerk nicht.
|
|
Raven280438 
      
Beiträge: 99
|
Verfasst: Mo 11.08.14 14:05
Hi,
Entschuldigung, da hatte ich nen Denkfehler drin.
Nur die OpenVPN-Verbindung soll per Service erstellt werden. Das Netzlaufwerk soll dann in einem andernen Programm angelegt werden.
Wie kann man dann am Besten den Service abfragen, ob das OpenVPN verbunden ist?
Ich hab von IPC bzw. WCF gelesen, weis aber nicht genau wie das mit Windows-Services funktioniert...
Kann mir da jemand weiterhelfen?
Gruß
|
|
Raven280438 
      
Beiträge: 99
|
Verfasst: Di 12.08.14 09:48
Hi,
ich hab im MSDN jetzt ein Beispiel gefunden:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66:
| using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; using Microsoft.Win32;
namespace ServiceApp { public class MyWinService : System.ServiceProcess.ServiceBase {
public MyWinService() { this.CanPauseAndContinue = false;
this.ServiceName = "MyWinService"; }
System.Runtime.Remoting.Channels.Ipc.IpcServerChannel ipcServer = null; protected override void OnStart(string[] args) { base.OnStart(args);
if (ipcServer == null) { System.Collections.IDictionary properties = new System.Collections.Hashtable(); properties["name"] = "ipc"; properties["authorizedGroup"] = "Everyone"; properties["portName"] = "MyServicePort"; ipcServer = new System.Runtime.Remoting.Channels.Ipc.IpcServerChannel(properties, null); System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(ipcServer, false); System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownServiceType(typeof(ControlClass), "MyServiceControl", System.Runtime.Remoting.WellKnownObjectMode.Singleton); Console.WriteLine(ipcServer.GetChannelUri()); } }
protected override void OnStop() { base.OnStop(); if (ipcServer != null) System.Runtime.Remoting.Channels.ChannelServices.UnregisterChannel(ipcServer); ipcServer = null; }
protected override void OnShutdown() { base.OnShutdown(); }
protected override void OnPause() { base.OnPause(); }
protected override void OnContinue() { base.OnContinue(); }
}
[Serializable()] public class ControlClass : MarshalByRefObject, Interfaces.IMyControler { public int DoFunction(string command) { System.IO.File.WriteAllText("c:\\temp\\servicecommand.txt", command); return 1; } } } |
Meine Frage ist allerdings, wie die "ControlClass" jetzt an Informationen des Service kommt?
Kann mir da jemand weiterhelfen?
Gruß
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 12.08.14 09:53
Könntest du deine Frage biete irgendwie auf ein Problem beschränken? Du springst zwischen Problemen hin und her die nichts miteinander zu tun haben so das man sich schwer tut auf irgendwas einzugehen.
|
|
Raven280438 
      
Beiträge: 99
|
Verfasst: Di 12.08.14 10:28
Hi,
im Prinzip suche ich eine Möglichkeit, von einer Desktop-Anwendung mit einem Windows-Dienst zu komunizieren.
Dazu hab ich im MSDN den oben geposteten Code gefunden. Allerdings weis ich nicht, wie die "ControlClass"-Klasse benutzt wird um Informationen vom Service zur Desktop-Anwendung zu übertragen.
Gruß
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 12.08.14 11:07
Zitat: | Allerdings weis ich nicht, wie die "ControlClass"-Klasse benutzt wird um Informationen vom Service zur Desktop-Anwendung zu übertragen. |
Du benutzt einfach den von dir definierten IPC Kanal 'MyServiceControl'. Zum Beispiel mit der IpcClientChannel Klasse
C#-Quelltext 1: 2: 3: 4: 5:
| IpcClientChannel clientChannel = new IpcClientChannel(); ChannelServices.RegisterChannel(clientChannel); RemotingConfiguration.RegisterWellKnownClientType( typeof(ControlClass) , "ipc://MyServicePort/MyServiceControl" ); ControlClass cc = new ControlClass(); int i = cc.DoFunction("Blub"); |
|
|
Raven280438 
      
Beiträge: 99
|
Verfasst: Di 12.08.14 11:13
Hi,
danke für die Antwort.
Soweit klar.
Aber woher weis die "ControlClass"-Klasse, was beim Service vorsich geht?
Der Service muss ja irgendwie Informationen an die ControlClass-Klasse geben, die dann an den Client weitergeleitet werden können.
Und der Client muss im Gegenzug auch Befehle an den Service senden können.
Wie macht man das am Besten?
Gruß
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 12.08.14 11:24
Zitat: | Der Service muss ja irgendwie Informationen an die ControlClass-Klasse geben, die dann an den Client weitergeleitet werden können. |
Was sollten das für Informationen sein? Der Service hostet nur deine ControlClass. Wenn du über den Kanal einem Client was mitteilen willst muß das die ControlClass berechnen bzw. ermitteln. Der Service weiß ja auch nicht magisch mehr als die ControlClass. Beide wissen potentiell erstmal gar nichts. Wenn es also Informationen zu ermitteln gibt lass es einfach die ControlClass machen und von ihr zurückgeben.
|
|
Raven280438 
      
Beiträge: 99
|
Verfasst: Di 12.08.14 11:30
Hi,
also der Service soll eigendlich OpenVPN-Verbindungen aufbauen/trennen/etc.
Kann der Service nicht irgendwie Informationen an die ControlClass-Klasse weitergeben?
z.B. das eine OpenVPN-Verbindung besteht, und die ControlClass-Klasse gibt das dann an den Client weiter?
Oder muss die ControlClass die komplette Funktionalität übernehmen, und der Service hostet die Klasse nur?
Gruß
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 12.08.14 12:02
Zitat: | Oder muss die ControlClass die komplette Funktionalität übernehmen, und der Service hostet die Klasse nur? |
Die Service Klasse stellt denn Service dar der weiß also wie ein Service funktioniert und macht die Kommunikation mit dem Service Control Manager (starten, stoppen, pause etc.).
Deine ControlClass Klasse stellt das Interface für irgendeinen Client zur Verfügung. Keine von beiden sollte die konkrete Funktionalität enthalten. Die implementierst du natürlich in irgendeinem 3.ten sauber davon getrennten Klassenkonstrukt. Und das kann dann von ControlClass direkt verwendet werden. Es gibt keinen Grund die Service Klasse damit zu belasten. Ist weder deren Aufgabe noch wäre es irgendwie hilfreich.
|
|
Raven280438 
      
Beiträge: 99
|
Verfasst: Di 12.08.14 12:13
Hi,
danke für die Antwort.
Also nur, damit ich das richtig verstanden habe:
In der ControlClass findet, ausgelagert in ein anderes Programm-Konstrukt, die eigendliche Funktionalität statt?
Die Service-Klasse hat damit (abgesehen von der Funktion als IPC-Server) nichts damit zutun?
Gruß
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 12.08.14 12:44
So würde ich das sehen. Ja.
|
|
Raven280438 
      
Beiträge: 99
|
Verfasst: Di 12.08.14 13:10
Hi,
ok, danke.
Und der Code in der ControlClass wird dann auch mit den Service-Rechten etc. ausgeführt, auch wenn er vom Client aufgerufen wird?
Zum Erstellen von VPN-Routen etc. braucht man z.B. Admin-Rechte.
Gruß
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 12.08.14 13:23
Ich weiß nicht genau was der IPCChannel anstellt bezweifle aber das der Impersonation beherrscht. Insbesondere so wie du es im Moment machst würde das ausschließen da du ja deine ControlClass als Singleton benutzt. Wen sich alle parallel die selbe Klasseninstanz teilen kann/darf man das kaum mit unterschiedlichen Rechten. Da werden also mit ziemlicher Sicherheit die Userrechte ziehen unter dem der Service läuft. Wenn du SingleCall anstatt Singleton verwendest würde ich Impersonation zumindest für möglich halten. Denke aber das es da genausowenig enthalten ist. Wenn du den Service im Service per WCF hostest hast du definitiv Impersonation zur Verfügung. Wäre auch irgendwie die aktuellere Wahl gegenüber dem alten Remoting Zeugs.
Edit: Scheint doch zu gehen. Siehe hier
Edit2: Wo es gerade um Authorisierung geht. "Everyone" wird nur selten funktionieren. Das unterliegt der Globalisierung und du müßtest dort die lokale Bezeichnung (z.B "Jeder" in DE) verwenden.
Am besten gleich die SID benutzen.
|
|
Raven280438 
      
Beiträge: 99
|
Verfasst: Di 12.08.14 13:46
Hi,
hm also doch besser WCF nehmen?!
Dazu hab ich diese beiden Beispiele gefunden: Server/ Client
Kann man die als Grundlage erstmal so nehmen?
Wie gesagt, ich arbeite mich im Moment erstmal in das Thema ein, hatte bisher noch nichts mit IPC bzw. Windows Diensten zutun.
Gruß
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 12.08.14 13:52
Hab ich jetzt nur überflogen aber sieht ganz vernünftig aus.
|
|