调试Windows服务

时间:2010-04-13 13:07:56

标签: c# windows-services debugging

方案

我有一个用C#编写的Windows服务。 我已经阅读了有关如何调试它的所有谷歌线程,但我仍然无法让它工作。 我运行了“PathTo.NetFramework \ InstallUtil.exe C:\ MyService.exe”。它表示安装成功,但是当我运行“Services.msc”时,该服务根本不显示在任何地方。如果我进入任务管理器,有一个名为“MyService.vshost.exe”的进程。很确定不是它,因为它是一种服务,而不是一个过程。

有人可以向我解释一下吗?

如果我在运行Services.msc时应该看到该服务? (请记住,这一切都是在本地机器上完成的,没有任何服务器。

其他

我正在运行VS2008。

编辑:

这一切都在我的本地机器上完成,我没有服务器或访问任何服务器。 此外,我甚至不知道该服务是做什么的,我想调试它,所以我可以通过代码查看它是如何工作的(服务中的代码,而不是服务本身 - 对于你们任何一个聪明的裤子可能建议我看一个模板)。

编辑2:

这些都没有工作! 每当我尝试一些东西时,我都会得到一些关于必须使用NET START或安装服务的消息。

编辑3:

我正在运行VS2008。

我输入了这个: C:\ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \ InstallUtil.exe C:\ dev \ Restarter \ bin \ Release \ Restarter.exe

我得到了这个: Microsoft(R).NET Framework安装实用程序版本2.0.50727.3053 版权所有(c)Microsoft Corporation。保留所有权利。

运行事务安装。

开始安装的安装阶段。 查看C:\ dev \ Restarter \ bin \的日志文件内容 Release \ Restarter.exe程序集的进度。 该文件位于C:\ dev \ Restarter \ bin \ Release \ EDT.Restar ter.InstallLog。 安装程序集'C:\ dev \ Restarter \ bin \ Release \ Restarter.exe'。 受影响的参数是:    logtoconsole =    assemblypath = C:\ dev \ Restarter \ bin \ Release \ Restarter.exe    logfile = C:\ dev \ Restarter \ bin \ Release \ Restarter.InstallLog

安装阶段成功完成,提交阶段正在开始。 查看C:\ dev \ Restarter \ bin \的日志文件内容 Release \ Restarter.exe程序集的进度。 该文件位于C:\ dev \ Restarter \ bin \ Release \ Restar ter.InstallLog。 提交程序集'C:\ dev \ Restarter \ bin \ Release \ Restarter.exe'。 受影响的参数是:    logtoconsole =    assemblypath = C:\ dev \ Restarter \ bin \ Release \ Restarter.exe    logfile = C:\ dev \ Restarter \ bin \ Release \ Restarter.InstallLog

提交阶段已成功完成。

已完成交易安装。

C:\ Program Files \ Microsoft Visual Studio 9.0 \ VC>

然后我去了RUN - > SERVICES.MSC 我在那里什么都看不见。

任务管理器中有一个名为“Restarter.vshost.exe”的进程。

就是这样。

我只想安装和调试它。 我知道它有效(因为它运行并且不会崩溃)。 但是代码是由朋友编写的,我希望通过在调试模式下遍历它来理解底层代码。

11 个答案:

答案 0 :(得分:115)

我建议使用以下模式进行调试:

 var ServiceToRun = new SomeService(); 
 if (Environment.UserInteractive)
 {
    // This used to run the service as a console (development phase only)

    ServiceToRun.Start();

    Console.WriteLine("Press Enter to terminate ...");
    Console.ReadLine();

    ServiceToRun.DoStop();
 }
 else
 {
    ServiceBase.Run(ServiceToRun);
 }

编辑:确保您的目标是控制台应用程序,而不是Windows应用程序,否则它将无效。

答案 1 :(得分:23)

您可以通过将调试器附加到进程来调试它。您可以通过在程序启动时添加一行来完成此操作:

Debugger.Launch ();
添加using语句后

using System.Diagnostics; 

您需要将其放入条件块中,或者在完成调试后将其删除

或运行服务,然后从IDE手动附加到流程:Debug-> Attach to process ..

答案 2 :(得分:6)

我们可以通过添加一个参数并使其表现得像控制台应用程序来使Windows服务项目可调试。

1)转到Windows服务项目属性 - >调试 - >启动选项 2)给出一个参数-Console 3)转到应用程序选项卡 - >输出类型,将其更改为控制台应用程序 4)在Program.cs中键入以下代码

static class Program
    {
        private static EventWaitHandle _waitHandle;
        private static Service1 _service;
                static void Main(string[] args)
        {
            bool runConsole = false;**

            foreach (string arg in args)
            {
                if (arg.ToLowerInvariant().Equals("-console"))
                {
                    runConsole = true;
                }
            }   

            _service = new Service1();
            if (runConsole)
            {
                _waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
                Console.WriteLine("Starting Workflow Service in Console Mode");
                Console.WriteLine("Press Ctrl+C to exit Console Mode");
               Console.CancelKeyPress += new ConsoleCancelEventHandler(OnCancelKeyPress);
                _service.InternalStart();
                WaitHandle.WaitAll(new WaitHandle[] { _waitHandle });
            }

            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new Service1() 
            };
            ServiceBase.Run(ServicesToRun);
        }

        static void OnCancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            _service.InternalStop();
            _waitHandle.Set();
        }


    }

答案 3 :(得分:5)

在开发/调试Windows服务时,这对我有很大帮助:

http://windowsservicehelper.codeplex.com/

按F5进行调试。很容易。

安德烈的做法也非常好。

答案 4 :(得分:4)

为了能够在不部署服务的情况下调试我的服务,我总是按照以下方式编写它:

在program.cs文件中:

#if DEBUG
    MyService myService = new MyService();
    myService.OnDebug();
    System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#else
    ServiceBase[] ServicesToRun;
    ServicesToRun = new ServiceBase[]
    {
        new MyService()
    };
    ServiceBase.Run(ServicesToRun);
#endif

并在您的MyService.cs文件中:

    public void OnDebug()
    {
        OnStart(null);
    }

*注意* :当您最终完成调试并准备好部署服务时,您必须在“发布”模式下构建,否则该服务将不被视为服务。

希望这有帮助。

答案 5 :(得分:2)

<强>假设:

1)您在VS2008 IDE的解决方案中有源代码

我如何调试C#服务:

  1. 使用InstallUtil安装服务。 (你好像已经这样做了)
  2. (如果需要)Change the Service path到解决方案bin文件夹中生成的MyService.exe
  3. 在服务OnStart()方法的开头添加以下内容:

    while(true)
    {
       System.Threading.Thread.Sleep(500);
    }
    
  4. System.Threading.Thread.Sleep(500)

  5. 上设置断点
  6. 构建解决方案

  7. 使用Windows Service Utility

  8. 启动服务
  9. 在您的服务启动时,在VS2008中转到Debug -> Attach To Processes...

  10. 确保选中Show Processes From All UsersShow Processes In All Sessions

  11. 在列表中找到您的MyService.exe,然后点击Attach

  12. 您现在应该处于无限循环中插入的断点

  13. 在无限循环外拖动控制(黄色箭头)

  14. 调试!

  15. <强>声明:

    当您想要发布版本时,或者只是想要正常运行服务时,请记住删除无限循环。

答案 6 :(得分:1)

可能是服务名称不是您所期望的,这就是您无法找到它的原因。服务名称在.NET项目的ServiceInstaller属性中定义,并且不必以任何方式与可执行文件名对应。但是,如果您确定安装后未列出该服务,则可以执行以下操作。

首先,服务安装。有两种方法InstallUtil.exeSC.exe。第一个是专门为.NET服务量身定制的,因为它将运行所有ProjectInstallerServiceInstaller代码。第二个不会这样做,但它会给你更多选择,通常更有效,即在InstallUtil失败时可能成功。这可能是在任何安装程序代码中出现异常时。

您已尝试使用InstallUtil安装,因此这里是SC版本:

sc create MyService binPath= "C:\Service.exe"

请注意,此处MyService给予服务的名称,它可以是您喜欢的任何内容(在理由中:-)。该名称将显示在服务控制台列表中。

安装服务后,您需要在调用OnStart时进行调试。这可以通过从服务中运行并附加到调试器(Visual Studio)来实现:

protected override void OnStart(string[] args)
{
    #if DEBUG
    Debugger.Launch();
    #endif
    ...
}

在此代码更改后,不要忘记构建和替换服务可执行文件。必须停止服务,但无需卸载并重新安装。

使用SC删除服务:

sc delete MyService

答案 7 :(得分:0)

如果您的业务层与Windows服务分开,则可以在运行Windows服务之外测试所有业务功能。

要测试Windows服务,我想创建一个控制台应用程序的测试项目,然后启动一个运行我的服务的新线程。

System.Threading.Thread sftpThread = new System.Threading.Thread((ThreadStart)service1);
service1.Start();

答案 8 :(得分:0)

我最近将这个添加到了一个项目中,它对我很有用。你可以像任何其他EXE一样调试它。添加之后,转到项目属性,并在Debug选项卡的Debug选项卡中添加命令行参数(/ EXE)。

<MTAThread()> _
Shared Sub Main()

    '' 
    '' let's add a command line parameter so we can run this as a regular exe or as a service
    ''
    If Command().ToUpper() = "/EXE" Then
        Dim app As MyService = New MyService()

        app.OnStart(Nothing)
        Application.Run()
    Else
        Dim ServicesToRun() As System.ServiceProcess.ServiceBase

        ' More than one NT Service may run within the same process. To add
        ' another service to this process, change the following line to
        ' create a second service object. For example,
        '
        '   ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1, New MySecondUserService}
        '
        ServicesToRun = New System.ServiceProcess.ServiceBase() {New MyService}

        System.ServiceProcess.ServiceBase.Run(ServicesToRun)
    End If
End Sub

答案 9 :(得分:0)

我建议在项目属性调试选项卡上添加/test作为开始选项。然后,您无需安装即可运行服务。

答案 10 :(得分:0)

如果使用TopShelf创建服务,则应该能够从Visual Studio轻松调试它