How to write c# - Dienst, ich kann auch eine winforms-Programm?
Ich habe einen windows service in C# geschrieben, die als proxy fungiert für eine Reihe von Netzwerk-Geräte an die back-end-Datenbank. Zum testen und auch zum hinzufügen eines Simulations-Schicht zu testen, das Backend würde ich gerne eine GUI für den test operator in der Lage sein, starten Sie die simulation. Auch eine gestreifte version runter zu senden, als eine demo. Der GUI-und service müssen nicht zur gleichen Zeit laufen. Was ist der beste Weg, dies zu erreichen Duell-Betrieb?
Bearbeiten:
Hier ist meine Lösung kämmen Sachen von diese Frage , Bin ich als Dienst Ausgeführt wird und Installieren Sie eine .NET windows-Dienst ohne InstallUtil.exe mit diese ausgezeichnete code von Marc Gravell
Verwendet es die folgende Zeile, um zu testen ob laufen der gui oder als service ausführen.
if (arg_gui || Environment.UserInteractive || Debugger.IsAttached)
Hier ist der code.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.ComponentModel;
using System.ServiceProcess;
using System.Configuration.Install;
using System.Diagnostics;
namespace Form_Service
{
static class Program
{
///
///The main entry point for the application.
///
[STAThread]
static int Main(string[] args)
{
bool arg_install = false;
bool arg_uninstall = false;
bool arg_gui = false;
bool rethrow = false;
try
{
foreach (string arg in args)
{
switch (arg)
{
case "-i":
case "-install":
arg_install = true; break;
case "-u":
case "-uninstall":
arg_uninstall = true; break;
case "-g":
case "-gui":
arg_gui = true; break;
default:
Console.Error.WriteLine("Argument not expected: " + arg);
break;
}
}
if (arg_uninstall)
{
Install(true, args);
}
if (arg_install)
{
Install(false, args);
}
if (!(arg_install || arg_uninstall))
{
if (arg_gui || Environment.UserInteractive || Debugger.IsAttached)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
rethrow = true; //so that windows sees error...
ServiceBase[] services = { new Service1() };
ServiceBase.Run(services);
rethrow = false;
}
}
return 0;
}
catch (Exception ex)
{
if (rethrow) throw;
Console.Error.WriteLine(ex.Message);
return -1;
}
}
static void Install(bool undo, string[] args)
{
try
{
Console.WriteLine(undo ? "uninstalling" : "installing");
using (AssemblyInstaller inst = new AssemblyInstaller(typeof(Program).Assembly, args))
{
IDictionary state = new Hashtable();
inst.UseNewContext = true;
try
{
if (undo)
{
inst.Uninstall(state);
}
else
{
inst.Install(state);
inst.Commit(state);
}
}
catch
{
try
{
inst.Rollback(state);
}
catch { }
throw;
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
}
}
[RunInstaller(true)]
public sealed class MyServiceInstallerProcess : ServiceProcessInstaller
{
public MyServiceInstallerProcess()
{
this.Account = ServiceAccount.NetworkService;
}
}
[RunInstaller(true)]
public sealed class MyServiceInstaller : ServiceInstaller
{
public MyServiceInstaller()
{
this.Description = "My Service";
this.DisplayName = "My Service";
this.ServiceName = "My Service";
this.StartType = System.ServiceProcess.ServiceStartMode.Manual;
}
}
}
- Wie kann ich es als Dienst? Ich führe mein Programm aus der cmd Schreibe ich c:\myservice.exe -installieren nichts geht. Wenn ich nur schreiben c:\myservice.exe beim öffnen meiner Anwendung. Was ich falsch mache. Oder wie kann ich es nutzen?
- hast du jemals den Sinn der Lösung unten? soweit die Erstellung der wrapper-Klassen und so?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie grundsätzlich zwei Möglichkeiten. Entweder setzen Sie eine API auf den Dienst, die können Sie dann Anruf von der UI-app ODER aktivieren Sie den Dienst ausführen, entweder als winforms-Anwendung oder ein Dienst.
Die erste option ist sehr einfach mit remoting oder WCF setzen Sie den API.
Die zweite option kann erzielt werden, indem man die "Eingeweide" der app in eine separate Klasse erstellen Sie anschließend ein service wrapper und eine win-forms wrapper, die sowohl call-in Ihre "Mut" - Klasse.
Erstellen Sie eine neue winforms-app, die die assembly verweist in Ihrem Dienst.
Wenn Sie verwenden Sie den folgenden code:
Dann die EXE ausgeführt wird, entweder ein service (wenn gestartet, durch die SCM) oder einer GUI (wenn gestartet, die von keinem anderen Prozess).
Im wesentlichen, alles, was ich getan habe, ist hier verwendet Reflektor, um herauszufinden, was das Fleisch von
ServiceBase.Run
tut, und duplizieren Sie es hier (Reflexion ist notwendig, weil es fordert, die privaten Methoden). Der Grund für den Aufruf nichtServiceBase.Run
direkt ist, dass es öffnet sich eine message box sagen, die Benutzer, dass der Dienst nicht gestartet werden kann (falls nicht gestartet, indem die SCM) und nicht wieder etwas zu sagen, die code, dass der Dienst nicht gestartet werden kann.Weil diese verwendet reflektion, um zu rufen private framework-Methoden, es möglicherweise nicht ordnungsgemäß in zukünftigen Versionen des Frameworks. VORBEHALT Kondor.
Gibt es auch FireDaemon. Dies ermöglicht das ausführen beliebigen windows-Anwendung als Dienst.
Sehen Bin ich als Dienst ausgeführt wird für einige weitere nützliche Informationen.
Das wichtigste abgedeckt ist, wie man zuverlässig feststellen, ob wir interaktiv oder über einen Dienstleister.
implementieren Sie einen separaten Prozess, der die Kommunikation mit Ihrem service. Zwar ist es möglich auf XP und früheren Systemen, um einen service haben, zeigt ein UI, das ist nicht mehr möglich unter Vista und höher.
Andere Möglichkeit ist die Verwendung NICHT eine Dienstleistung, sondern um eine Anwendung verwenden, die sich in der Taskleiste (glaube von Roxio Drag-to-Disc & wahrscheinlich dein Anti-virus-software, die dort unten lebt), die hat ein Symbol unten neben der Uhr, die gestartet wird, ein Menü, wenn Sie mit der rechten Maustaste geklickt, und ein UI-wenn man Sie doppelt anklickt.
Wenn Ihr service moduliert richtig, Sie hosten könnte der Dienst entweder in eine ausführbare Datei als Dienst, oder eine ausführbare Datei mit gui für den test.
Wir verwenden diese Methode mit unserem service auch die standalone-service-executable, die den Dienst hostet, in der produktiv-Umgebung, aber wir haben ein console-app für das hosting der service auch.
Trennen Sie Ihren code in verschiedenen Komponenten: eine Komponente zum verwalten der service-Aspekte und eine auf die eigentliche business-Logik. Erstellen von und interagieren mit der business-Logik von der service-Komponente. Für die Prüfung (Ihrer business-Logik), können Sie erstellen eine Windows forms oder console-Anwendungen, die die business-Logik-Komponente, ohne die service-Komponente. Besser noch, verwenden Sie ein unit-Test-framework für die Masse Ihrer Prüfung. Viele der Methoden, die in der service-Komponente, die zweifellos Einheit getestet werden, wie gut.
Wenn Sie Kapseln Geschäftslogik im service-Klassen zu verwenden und dann ein factory-Muster zu erstellen, die diese Dienste verwenden, können Sie den gleichen Satz von Diensten für eine desktop-Anwendung (desktop-factory) und als web-Dienste (host WCF).
Service-definition:
Fabrik für desktop WinForms, um auf Dienste, um Geschäfte zu machen:
Hosten Sie diese entweder mit dem WCF-ServiceHost-Klasse, oder in IIS. Beide erlauben Ihnen die Fähigkeit zu geben, wie zu instanzieren, für jede Instanz des service, so dass Sie tun können, Initialisierung, wie z.B. Verbindungs-strings, etc.
Können Sie erstellen den Dienst zu rufen, eine andere ausführbare Datei mit einem Kommandozeilen-argument, sodass es ausgeführt wird, ohne form. Wenn die exe aufgerufen wird, ohne das Kommandozeilenargument, es zeigt die form und Handlung als normal.