2012-10-12 7 views
13

Ich habe Win Service-Programm entwickelt, das eine Excel-Datei von meinem lokalen Laufwerk liest und dann diese Dateiwerte in der Datenbank speichert und nun ein Benachrichtigungssymbol entwickeln möchte, das angezeigt wird, um eine Nachricht anzuzeigen (" Excel-Datei gespeichert in der Datenbank ") nach meinem Dienst wird gestartet und Excel-Datei in der Datenbank speichern.Notify Icon für Window Service

Bitte geben Sie mir einige Hinweise, um dies zu lösen.

Antwort

13

Ab Vista darf Ihr Dienst nicht mehr mit dem Desktop interagieren, daher kann keine Benutzeroberfläche direkt aus dem Dienst ausgeführt werden. Sie müssen eine Agentenanwendung erstellen, die bei der Benutzeranmeldung startet und mit Ihrem Dienst chatten kann (möglicherweise mithilfe von WCF).

Hier ist, was MS have to say über das Tun dies:

Für komplexere Interaktionen, Entwickler ihre UI-Code in einen Agenten bewegen sollte, die in der Sitzung des Benutzers ausgeführt wird und kümmert sich um alle UI-Anforderungen. Der Agent kommuniziert über RPC oder Named Pipes mit dem Dienst. Wenn der Benutzer die Benutzeroberflächeninteraktion über die Systemsteuerung, Internet Explorer oder eine ähnliche Benutzeroberfläche einleitet, sollte diese Benutzeroberflächenerfahrung den Agenten starten. Der Agent verarbeitet dann alle Benutzeroberflächeninteraktionen. Wenn die Benutzeroberfläche erforderlich ist, aber nicht vom Benutzer initiiert wird, muss der Dienst den Agenten auffordern, eine erforderliche Benutzeroberfläche zu starten, anstatt zu versuchen, diese Benutzeroberfläche selbst zu starten. In der seltenen Situation, in der der Dienst eine Benutzerinteraktion initiieren muss und der Agent nicht bereits ausgeführt wird, sollte der Dienst die CreateProcessAsUser-API aufrufen, um den Agenten zu starten. Der Agent kann dann alle UI-Interaktionen initiieren. Es ist wichtig, dass Entwickler alle möglichen Verwendungsszenarien sorgfältig prüfen und den gesamten Benutzeroberflächencode in einen Agenten verschieben, der in der Benutzersitzung ausgeführt wird.

2

Das Problem hier ist, dass ein Windows-Dienst im Hintergrund ausgeführt wird und keinen Einfluss auf den Desktop des Benutzers hat.

Sie könnten eine Anwendung ähnlich wie diesen (ohne das Windows-Formular) erstellen: Notify Icon control in .Net 2.0

Und dann so etwas wie die folgende Klasse in der Anwendung verwenden, um mit dem Windows-Dienst zu kommunizieren:

public class Program 
{ 
    public int Setting { get; set; } 
} 

[ServiceContract] 
public interface ISettingService 
{ 
    [OperationContract] 
    void SetSetting(int setting); 
} 

public class SettingService : ISettingService 
{ 
    private readonly Program program; 

    public SettingService(Program program) 
    { 
     this.program = program; 
    } 

    public void SetSetting(int setting) 
    { 
     program.Setting = setting; 
    } 
} 

internal class CustomInstanceProvider : IInstanceProvider 
{ 
    private readonly Program program; 

    public CustomInstanceProvider(Program program) 
    { 
     this.program = program; 
    } 

    public object GetInstance(InstanceContext instanceContext, Message message) 
    { 
     return GetInstance(instanceContext); 
    } 

    public object GetInstance(InstanceContext instanceContext) 
    { 
     return new SettingService(program); 
    } 

    public void ReleaseInstance(InstanceContext instanceContext, object instance) 
    { 
     IDisposable disposable = instance as IDisposable; 
     if (disposable != null) 
     { 
      disposable.Dispose(); 
     } 
    } 
} 

internal class CustomInstanceProviderBehaviorAttribute : Attribute, IServiceBehavior 
{ 
    private readonly IInstanceProvider instanceProvider; 

    public CustomInstanceProviderBehaviorAttribute(IInstanceProvider instanceProvider) 
    { 
     this.instanceProvider = instanceProvider; 
    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers) 
     { 
      foreach (EndpointDispatcher ed in cd.Endpoints) 
      { 
       if (!ed.IsSystemEndpoint) 
       { 
        ed.DispatchRuntime.InstanceProvider = instanceProvider; 
       } 
      } 
     } 
    } 

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } 
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } 
} 

public class CustomServiceHost : ServiceHost 
{ 
    private readonly Program p; 

    public CustomServiceHost(Program program, params Uri[] baseAddresses) 
    : base(typeof(SettingService), baseAddresses) 
    { 
     this.p = program; 
    } 

    protected override void OnOpening() 
    { 
     Description.Behaviors.Add(new CustomInstanceProviderBehaviorAttribute(new CustomInstanceProvider(p))); 
     base.OnOpening(); 
    } 
} 
1

I denke, Sie brauchen NotifyIcon.ShowBalloonTip Methode in Ihrem Service zu implementieren. Sie müssen möglicherweise this lesen.

+0

Ein weiterer interessanter Link, den ich gefunden habe. Bitte werfen Sie einen Blick http://social.msdn.microsoft.com/Forums/da-DK/winforms/thread/2ceda452-1576-4372-8406-a463333800f7 –

+0

Sie haben Recht, ich möchte eigentlich tun, aber ich denke Fenster Service kann nicht mit Desktop-Coz von Sicherheitsproblemen interagieren. Hier ist eine Referenz. [link] (http://msdn.microsoft.com/en-us/windows/hardware/gg463353.aspx) –

+0

Dann sollten Sie entweder NotifyIcon gehen oder zwei Projekte erstellen. Eine Windows-App und Ihr tatsächlicher Dienst. Die Window App wird eine begrenzte Interaktion mit dem Dienst durchführen und hauptsächlich die NotifyIcon zeigen. –