15

ローカルドライブからExcelファイルを読み取り、このファイル値をデータベースに保存するwinサービスプログラムを開発しました。次に、メッセージを表示するために表示される通知アイコン( "Excel File Saved In Database")を開発したいと思います。サービスが開始され、Excelファイルがデータベースに保存されます。

これを解決するためのヒントを教えてください。

4

3 に答える 3

13

Vista以降では、サービスがデスクトップと対話することは許可されないため、サービスから直接UIを実行することはできません。(おそらくWCFを使用して)サービスとチャットできるユーザーログイン時に起動するエージェントアプリケーションを構築する必要があります。

これを行うことについてMSが言わなければならないことは次のとおりです。

より複雑な対話の場合、開発者はUIコードを、ユーザーのセッションで実行され、すべてのUI要件を処理するエージェントに移動する必要があります。エージェントは、RPCまたは名前付きパイプを介してサービスと通信します。ユーザーがコントロールパネル、Internet Explorer、または同様のUIエクスペリエンスを使用してUIインタラクションを開始した場合、そのUIエクスペリエンスはエージェントを開始する必要があります。次に、エージェントはすべてのUIインタラクションを処理します。UIが必要であるが、ユーザーによって開始されていない場合、サービスは、そのUIを単独で起動しようとするのではなく、必要なUIを開始するようにエージェントに要求する必要があります。サービスがユーザーインタラクションを開始する必要があり、エージェントがまだ実行されていないというまれな状況では、サービスはCreateProcessAsUserAPIを呼び出してエージェントを開始する必要があります。その後、エージェントはすべてのUIインタラクションを開始できます。

于 2012-10-12T10:37:31.940 に答える
2

ここでの問題は、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();
    }
}
于 2012-10-12T10:47:54.007 に答える
1

NotifyIcon.ShowBalloonTipサービスに実装するにはメソッドが必要だと思います。あなたはこれを読む必要があるかもしれません。

于 2012-10-12T11:33:47.620 に答える