5

我最近发现了 TopShelf。从我读过的所有内容来看,它看起来很酷。唯一的问题是我无法使用它。我一定错过了什么。下面是我的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;

namespace TestTopShelf {
public class FooBar {
    public FooBar() {

    }

    public void Start() { }
    public void Stop() { }
}

public class Program {
    public static void Main() {
        HostFactory.Run(x => {

            x.Service<FooBar>( s => { 

            });
        });
    }
}
}

你可以看到它有点不完整。当我尝试为 ConstructUsing、WhenStarted 和 WhenStopped 设置“s”对象的属性时,Visual Studio 没有推断出正确的类型。我是 lambda 表达式的新手,甚至是 TopShelf 的新手,所以我不确定我在做什么。

我正在使用TopShelf 文档中的这个页面来帮助我入门。它看起来很简单,所以我不确定我错过了什么。


更新代码


using Autofac;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;

namespace KeithLink.Svc.Windows.OrderService2 {
class FooBar {
    public FooBar() { }

    public void Start() { }
    public void Stop() { }
}

class Program {
    static void Main(string[] args) {
        HostFactory.Run(x => {

            x.Service<FooBar>(s => {
                s.ConstructUsing(name => new OrderService());
                s.WhenStarted(os => os.Start());
                s.WhenStopped(os => os.Stop());
            });

            x.RunAsLocalSystem();

            x.SetDescription("some service description");
            x.SetServiceName("ServiceName");
            x.SetDisplayName("Service Display Name");
        });
    }
}
}
4

2 回答 2

4

尽管 VisualStudio 的智能感知不能推断出正确的类型,但它仍然应该可以编译。我不知道 topshelf 在做什么,但我记得上次尝试使用它时遇到了这些问题。

于 2014-09-19T11:59:20.640 回答
3

当您想“注册”一项服务以在启动时使用 TopShelf 运行时,您调用该Service<T>.Run方法——您似乎已经开始使用该方法。在该方法中,您将传递一个HostConfigurator对象,您可以告诉(配置)TopShelf 您的服务。您可以对服务进行各种配置,但您通常希望告诉它如何实例化您的服务以及如何停止和启动它。您可以通过传入执行这些操作的“代码”来做到这一点。您可以使用 lambda 来执行此操作,例如:

public static void Main() {
    HostFactory.Run(x => {

        x.Service<FooBar>( s => { 
            s.ConstructUsing(name => new FooBar());
            s.WhenStarted(fb => fb.Start());
            s.WhenStopped(fb => fb.Stop());
        });
        x.RunAsLocalSystem(); // use the local system account to run as

        x.SetDescription("My Foobar Service");  // description seen in services control panel
        x.SetDisplayName("FooBar"); // friendly name seen in control panell
        x.SetServiceName("foobar"); // used with things like net stop and net start
    });
}

此代码不必是 la​​mbda,您可以创建方法来执行此操作(例如,这可能更清楚):

    private static void Main(string[] args)
    {
        HostFactory.Run(x =>
        {
            x.Service<FooBar>(s =>
            {
                s.ConstructUsing(CreateService);
                s.WhenStarted(CallStart);
                s.WhenStopped(CallStop);
            });
            x.RunAsLocalSystem(); // use the local system account to run as

            x.SetDescription("My Foobar Service");  // description seen in services control panel
            x.SetDisplayName("FooBar"); // friendly name seen in control panell
            x.SetServiceName("foobar"); // used with things like net stop and net start
        });
    }

    private static void CallStop(FooBar fb)
    {
        fb.Stop();
    }

    private static void CallStart(FooBar fb)
    {
        fb.Start();
    }

    private static FooBar CreateService(HostSettings name)
    {
        return new FooBar();
    }

这可以让您在上课时或多或少开始FooBar,如果有更具体的内容,请更新您的问题。

使用这些命名方法,当 TopShelf 开始运行时(在调用 之后HostFactory.Run)您的CreateSearch方法将被调用,然后您的CallStart方法将被调用,当服务停止时,您的方法CallStop将被调用。

于 2014-09-17T21:51:49.703 回答