2

我想启动一个刚刚安装的 Windows 服务。

ServiceBase[] ServicesToRun;
if (bool.Parse(System.Configuration.ConfigurationManager.AppSettings["RunService"]))
{
    ServicesToRun = new ServiceBase[] { new IvrService() };
    ServiceBase.Run(ServicesToRun);
}

IvrService 代码是:

partial class IvrService : ServiceBase
{
    public IvrService()
    {
        InitializeComponent();

        Process myProcess;
        myProcess = System.Diagnostics.Process.GetCurrentProcess();

        string pathname = Path.GetDirectoryName(myProcess.MainModule.FileName);

        //eventLog1.WriteEntry(pathname);

        Directory.SetCurrentDirectory(pathname);

    }

    protected override void OnStart(string[] args)
    {
        string sProcessName = Process.GetCurrentProcess().ProcessName;

        if (Environment.UserInteractive)
        {
            if (sProcessName.ToLower() != "services.exe")
            {
                // In an interactive session.
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new IvrInteractive());
                IvrApplication.Start(); // the key function of the service, start it here
                return;
            }
        }
    }

我不确定如何启动该服务。使用ServiceController.Start()?但我已经有ServiceBase.Run(ServicesToRun);它是用于启动服务吗?

代码提示绝对值得赞赏。

4

2 回答 2

5

要回答有关从代码启动服务的问题,您需要这样的内容(相当于net start myservice从命令行运行):

ServiceController sc = new ServiceController();
sc.ServiceName = "myservice";

if (sc.Status == ServiceControllerStatus.Running || 
    sc.Status == ServiceControllerStatus.StartPending)
{
    Console.WriteLine("Service is already running");
}
else
{
    try
    {
        Console.Write("Start pending... ");
        sc.Start();
        sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10));

        if (sc.Status == ServiceControllerStatus.Running)
        {
            Console.WriteLine("Service started successfully.");
        }
        else
        {
            Console.WriteLine("Service not started.");
            Console.WriteLine("  Current State: {0}", sc.Status.ToString("f"));
        }
    }
    catch (InvalidOperationException)
    {
        Console.WriteLine("Could not start the service.");
    }
}

这将启动服务,但请记住,这将是与执行上述代码的进程不同的进程。


现在回答有关调试服务的问题。

  • 一种选择是在服务启动后附加。
  • 另一个是使您的服务可执行文件能够运行主要代码,而不是作为服务,而是作为普通可执行文件(通常通过命令行参数设置)。然后你可以从你的 IDE 中按 F5 进入它。


编辑:添加事件流示例(基于一些评论中的问题)

  1. 操作系统被要求启动服务。这可以通过控制面板、命令行、API(如上面的代码)或由操作系统自动完成(取决于服务的启动设置)。
  2. 然后操作系统创建一个新进程。
  3. 然后,该进程注册服务回调(例如ServiceBase.Run在 C# 或StartServiceCtrlDispatcher本机代码中)。然后开始运行它的代码(它将调用你的ServiceBase.OnStart()方法)。
  4. 然后操作系统可以请求暂停、停止服务等。此时它将向已经运行的进程发送控制事件(从步骤 2 开始)。这将导致调用您的ServiceBase.OnStop()方法。


编辑:允许服务作为普通可执行文件或命令行应用程序运行:一种方法是将您的应用程序配置为控制台应用程序,然后根据命令行开关运行不同的代码:

static void Main(string[] args)
{
    if (args.Length == 0)
    {
        // we are running as a service
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] { new MyService() };
        ServiceBase.Run(ServicesToRun);
    }
    else if (args[0].Equals("/debug", StringComparison.OrdinalIgnoreCase))
    {
        // run the code inline without it being a service
        MyService debug = new MyService();
        // use the debug object here
    }
于 2013-10-02T15:48:39.177 回答
0

首先,您需要使用 InstallUtil 安装服务,例如

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe C:\MyService.exe

您需要从命令行启动服务,例如

net start ServiceName // whatever the service is called

然后,您需要通过工具 > 附加到进程,使用 Visual Studio 附加到进程。

将断点粘贴在解决方案中您希望它中断的任何位置,并且开发环境应该接管。

要从开发环境启动它,请将net start ServiceName命令放入批处理文件,然后在 Project Properties > Build Events “Post Build Event Command Line”中添加批处理文件的路径。

*请注意,现在看,我不确定您是否甚至需要使用批处理文件,您也许可以将命令直接放在那里。尝试使用任何有效的方法编辑此答案。

于 2013-10-02T15:26:35.053 回答