我已经开发了一个 win 服务程序,它从我的本地驱动器读取一个 excel 文件,然后将此文件值保存到数据库中,现在我想开发一个通知图标,它将在之后显示一条消息(“Excel 文件保存在数据库中”)我的服务将启动并将 excel 文件保存到数据库。
请给我一些提示来解决这个问题。
我已经开发了一个 win 服务程序,它从我的本地驱动器读取一个 excel 文件,然后将此文件值保存到数据库中,现在我想开发一个通知图标,它将在之后显示一条消息(“Excel 文件保存在数据库中”)我的服务将启动并将 excel 文件保存到数据库。
请给我一些提示来解决这个问题。
从 Vista 开始,您的服务将不允许与桌面交互,因此不能让 UI 直接在服务之外运行。您需要构建一个代理应用程序,该应用程序在用户登录时启动,可以与您的服务聊天(可能使用 WCF)。
以下是MS对此的评价:
对于更复杂的交互,开发人员应该将他们的 UI 代码移动到在用户会话中运行并处理所有 UI 要求的代理中。代理通过 RPC 或命名管道与服务通信。如果用户使用控制面板、Internet Explorer 或类似的 UI 体验启动 UI 交互,则该 UI 体验应启动代理。然后代理处理所有 UI 交互。如果需要 UI 但用户未启动,则服务必须请求代理启动任何所需的 UI,而不是尝试自行启动该 UI。在服务必须启动用户交互并且代理尚未运行的极少数情况下,服务应调用 CreateProcessAsUser API 来启动代理。然后代理可以启动所有 UI 交互。
这里的问题是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();
}
}
我认为您需要NotifyIcon.ShowBalloonTip
Method 在您的服务中实施。您可能需要阅读此内容。