2012-10-12 23 views
13

Ho sviluppato un programma di servizio win che legge un file excel dalla mia unità locale e quindi salva i valori di questo file nel database e ora voglio sviluppare un'icona di notifica che verrà visualizzata per mostrare un messaggio (" Excel File Saved In Database ") dopo l'avvio del mio servizio e il salvataggio del file excel nel database.Notifica icona per il servizio finestra

Per favore, dammi qualche suggerimento per risolvere questo.

risposta

13

Da Vista in poi, il servizio non sarà in grado di interagire con il desktop, quindi non è possibile eseguire un'interfaccia utente direttamente dal servizio. È necessario creare un'applicazione agente che si avvia all'accesso utente in grado di chattare con il proprio servizio (magari utilizzando WCF).

Ecco cosa MS have to say a fare questo:

Per interazioni più complesse, gli sviluppatori dovrebbero spostare il loro codice di interfaccia utente in un agente che viene eseguito in sessione dell'utente e gestisce tutte le esigenze di interfaccia utente. L'agente comunica con il servizio tramite RPC o named pipe. Se l'utente avvia l'interazione dell'interfaccia utente utilizzando il Pannello di controllo, Internet Explorer o un'interfaccia utente simile, l'esperienza dell'interfaccia utente deve avviare l'agente. L'agente quindi gestisce tutte le interazioni dell'interfaccia utente. Se l'interfaccia utente è richiesta ma non viene avviata dall'utente, il servizio deve richiedere all'agente di avviare qualsiasi interfaccia utente richiesta, anziché tentare di avviare tale interfaccia utente autonomamente. Nella rara situazione in cui il servizio deve avviare un'interazione utente e l'agente non è già in esecuzione, il servizio deve chiamare l'API CreateProcessAsUser per avviare l'agente. L'agente può quindi avviare tutte le interazioni dell'interfaccia utente. È importante che gli sviluppatori riesaminino attentamente tutti i possibili scenari di utilizzo e considerino lo spostamento di tutto il codice dell'interfaccia utente in un agente che viene eseguito nella sessione utente.

2

Il problema è che un servizio Windows viene eseguito in background e non ha alcun impatto sul desktop dell'utente.

Si potrebbe creare un'applicazione simile a questo (senza la forma di Windows): Notify Icon control in .Net 2.0

E poi usare qualcosa come la seguente classe nell'applicazione per comunicare con il servizio di Windows:

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 pensa di aver bisogno del metodo NotifyIcon.ShowBalloonTip da implementare nel tuo servizio. Potrebbe essere necessario leggere this.

+0

Un altro collegamento interessante che ho trovato. per favore dai un'occhiata http://social.msdn.microsoft.com/Forums/da-DK/winforms/thread/2ceda452-1576-4372-8406-a463333800f7 –

+0

hai ragione, in realtà voglio farlo, ma penso che il servizio in finestra non posso interagire con desktop coz di problemi di sicurezza. ecco un riferimento. [collegamento] (http://msdn.microsoft.com/en-us/windows/hardware/gg463353.aspx) –

+0

Quindi non si dovrebbe andare a NotifyIcon o creare due progetti. Un'app di Windows e il servizio effettivo. Window App comporterà un'interazione limitata con il servizio e principalmente mostrerà il NotifyIcon. –

Problemi correlati