我开发了win服务程序,它从我的本地驱动器读取excel文件,然后将此文件值保存到数据库,现在我想开发一个通知图标,显示一条消息(“Excel文件保存在数据库中“)我的服务将启动并将excel文件保存到数据库。
请给我一些解决方法。
答案 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。