通知Window Service的图标

时间:2012-10-12 10:35:25

标签: c# visual-studio-2010 windows-services

我开发了win服务程序,它从我的本地驱动器读取excel文件,然后将此文件值保存到数据库,现在我想开发一个通知图标,显示一条消息(“Excel文件保存在数据库中“)我的服务将启动并将excel文件保存到数据库。

请给我一些解决方法。

3 个答案:

答案 0 :(得分:13)

从Vista开始,您的服务将无法与桌面交互,因此无法直接从服务中运行UI。您需要构建一个代理应用程序,该应用程序在用户登录时启动,可以与您的服务聊天(可能使用WCF)。

以下是关于这样做的MS have to say

  

对于更复杂的交互,开发人员应将其UI代码移动到在用户会话中运行的代理并处理所有UI要求。代理通过RPC或命名管道与服务进行通信。如果用户使用控制面板,Internet Explorer或类似的UI体验启动UI交互,则该UI体验应启动代理。然后代理处理所有UI交互。如果UI是必需的但不是由用户启动,则服务必须请求代理启动任何所需的UI,而不是尝试自己启动该UI。在极少数情况下,服务必须启动用户交互并且代理尚未运行,服务应调用CreateProcessAsUser API以启动代理。然后,代理可以启动所有UI交互。对于开发人员来说,仔细检查所有可能的使用场景并考虑将所有UI代码移动到在用户会话中运行的代理是很重要的。

答案 1 :(得分: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();
    }
}

答案 2 :(得分:1)

我认为您需要NotifyIcon.ShowBalloonTip方法在您的服务中实施。 您可能需要阅读this