ローカルドライブからExcelファイルを読み取り、このファイル値をデータベースに保存するwinサービスプログラムを開発しました。次に、メッセージを表示するために表示される通知アイコン( "Excel File Saved In Database")を開発したいと思います。サービスが開始され、Excelファイルがデータベースに保存されます。
これを解決するためのヒントを教えてください。
ローカルドライブからExcelファイルを読み取り、このファイル値をデータベースに保存するwinサービスプログラムを開発しました。次に、メッセージを表示するために表示される通知アイコン( "Excel File Saved In Database")を開発したいと思います。サービスが開始され、Excelファイルがデータベースに保存されます。
これを解決するためのヒントを教えてください。
Vista以降では、サービスがデスクトップと対話することは許可されないため、サービスから直接UIを実行することはできません。(おそらくWCFを使用して)サービスとチャットできるユーザーログイン時に起動するエージェントアプリケーションを構築する必要があります。
これを行うことについてMSが言わなければならないことは次のとおりです。
より複雑な対話の場合、開発者はUIコードを、ユーザーのセッションで実行され、すべてのUI要件を処理するエージェントに移動する必要があります。エージェントは、RPCまたは名前付きパイプを介してサービスと通信します。ユーザーがコントロールパネル、Internet Explorer、または同様のUIエクスペリエンスを使用してUIインタラクションを開始した場合、そのUIエクスペリエンスはエージェントを開始する必要があります。次に、エージェントはすべてのUIインタラクションを処理します。UIが必要であるが、ユーザーによって開始されていない場合、サービスは、そのUIを単独で起動しようとするのではなく、必要なUIを開始するようにエージェントに要求する必要があります。サービスがユーザーインタラクションを開始する必要があり、エージェントがまだ実行されていないというまれな状況では、サービスはCreateProcessAsUserAPIを呼び出してエージェントを開始する必要があります。その後、エージェントはすべてのUIインタラクションを開始できます。
ここでの問題は、Windowsサービスがバックグラウンドで実行され、ユーザーのデスクトップに影響を与えないことです。
これに似たアプリケーションを作成できます(Windowsフォームなし):.Net2.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
サービスに実装するにはメソッドが必要だと思います。あなたはこれを読む必要があるかもしれません。