2012-10-12 79 views
13

我開發了win服務程序,它從本地驅動器中讀取excel文件,然後將此文件值保存到數據庫,現在我想開發一個通知圖標,它將顯示以顯示消息(「保存在數據庫中的Excel文件「)後,我的服務將啓動並將Excel文件保存到數據庫。窗口服務的通知圖標

請給我一些提示來解決這個問題。

回答

13

從Vista開始,您的服務將不被允許與桌面交互,因此無法直接從服務中運行UI。您需要構建一個代理應用程序,該應用程序在用戶登錄時啓動,可以與您的服務聊天(可能使用WCF)。

下面是關於這樣做有什麼MS have to say

對於更復雜的交互,開發者應該將他們的UI代碼到用戶的會話中運行,並處理所有UI要求代理。代理通過RPC或命名管道與服務進行通信。如果用戶使用控制面板,Internet Explorer或類似的UI體驗啓動UI交互,則該UI體驗應啓動代理。代理然後處理所有UI交互。如果UI是必需的,但不是由用戶發起的,則服務必須請求代理啓動任何所需的UI,而不是嘗試單獨啓動該UI。在極少情況下,服務必須啓動用戶交互並且代理程序尚未運行,服務應調用CreateProcessAsUser API來啓動代理程序。代理可以啓動所有UI交互。開發人員仔細查看所有可能的使用場景並考慮將所有UI代碼移動到在用戶會話中運行的代理中,這一點非常重要。

2

這裏的問題在於,Windows服務在後臺運行,並且不會影響用戶的桌面。

您可以創建類似這樣的應用程序(不包括Windows窗體):Notify Icon control in .Net 2.0

然後使用類似下面的類應用程序與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

我認爲你需要NotifyIcon.ShowBalloonTip方法來實現你的服務。 您可能需要閱讀this

+0

我發現了另一個有趣的鏈接。請看看http://social.msdn.microsoft.com/Forums/da-DK/winforms/thread/2ceda452-1576-4372-8406-a463333800f7 –

+0

你是對的我其實想這樣做,但我認爲窗口服務不能與臺式機的安全問題相互作用。這裏是參考。 [鏈接](http://msdn.microsoft.com/en-us/windows/hardware/gg463353.aspx) –

+0

然後,要麼你不應該去爲NotifyIcon或創建兩個projects.A Windows應用程序和您的實際服務。 Window App將與服務進行有限的交互,主要是顯示NotifyIcon。 –