【问题标题】:Problem with testing a Windows service测试 Windows 服务的问题
【发布时间】:2011-02-04 09:57:32
【问题描述】:

我想创建一个可以访问我的数据库的 Windows 服务。我的数据库是 SQL Server 2005。

实际上,我正在开发一个网站,而我的数据库位于我们的服务器中。我需要每秒访问我的数据库并更新记录。为此,我需要创建一个 Windows 服务,该服务将安装到我们的服务器中并执行任务。

我一直在从本地机器访问数据库,然后运行该服务,但问题是我不确定如何测试该服务。

我试图安装到我的本地机器上。它安装了,然后我运行了服务,但它没有执行任务,我认为服务无法连接到数据库。

服务和安装程序都没有问题。唯一的问题是如何测试我的 Windows 服务。

【问题讨论】:

    标签: c# windows sql-server-2005 windows-services


    【解决方案1】:

    您始终可以创建服务/控制台应用混合,并将控制台应用用于测试目的。

    您需要做的是这样的 - 在您的 program.cs 中,更改 Main 方法以运行该服务,或者选择作为控制台应用程序运行:

    static class Program
    {
        static void Main(params string[] args)
        {
            string firstArgument = string.Empty;
    
            if (args.Length > 0)
            {
                firstArgument = args[0].ToLowerInvariant();
            }
    
            if (string.Compare(firstArgument, "-console", true) == 0)
            {
                new YourServiceClass().RunConsole(args);
            }
            else
            {
                ServiceBase[] ServicesToRun = new ServiceBase[] { new YourServiceClass() };
                ServiceBase.Run(ServicesToRun);
            }
        }
    

    然后在继承自ServiceBase 并具有OnStartOnStop 的服务类上,添加RunConsole 方法,如下所示:

        public void RunConsole(string[] args)
        {
            OnStart(args);
    
            Console.WriteLine("Service running ... press <ENTER> to stop");
    
            //Console.ReadLine();
            while (true)
            { }
    
            OnStop();
        }
    

    现在,如果您想运行应用程序以测试其功能,只需使用 -console 命令行参数启动 EXE,然后在 RunConsole 方法中放置一个断点。

    【讨论】:

    • +1 这应该是公认的答案,因为这也会在您有机会附加到流程之前发现问题。
    • 顺便说一句,OnStop() 无法访问。
    • 为什么 Console.ReadLine() 被注释掉了?这不正确吗?摆脱无限循环...
    • 为了摆脱 Phil 建议的无限循环,我对函数进行了一些修改,并在下面的答案中发布...
    • @kalengi 下面的帖子完成了这个答案。干得好!
    【解决方案2】:

    您可以将 Visual Studio 解决方案附加到 Windows 服务应用程序。然后就可以像做普通项目一样调试windows服务了。

    调试 --> 附加到进程。

    【讨论】:

      【解决方案3】:

      使用记录器报告错误!

      尝试捕获所有可能的错误并将它们记录在文件中和/或最好发送电子邮件:记住“没有人听到服务死亡”!

      Log4Net 有记录器来处理滚动文件、数据库持久性甚至 SMTP 消息。例如,请参阅:http://logging.apache.org/log4net/release/config-examples.html 您可能必须定期检查日志文件中的错误。为了避免这种繁琐的工作,我经常使用 SMTP appender。

      干杯, B.

      【讨论】:

        【解决方案4】:

        marc_s 的回答是完美的,但事实上服务的主线程并没有按预期暂停等待用户输入。我认为这就是他陷入无限循环的原因。

        借用Igal Serban's 创建控制台的代码,这里是对确实暂停的RunConsole() 方法的增强:

            [DllImport("kernel32.dll", SetLastError = true)]
            static extern bool AllocConsole();
        
            [DllImport("kernel32.dll", SetLastError = true)]
            static extern bool FreeConsole();
        
            public void RunConsole(string[] args)
            {
                OnStart(args);
        
                AllocConsole();
        
                Console.WriteLine("Service running ... press <ENTER> to stop");
        
                Console.ReadLine();
        
                FreeConsole();
        
                OnStop();
            }
        

        【讨论】:

        • 谢谢,这个完美的! :-)
        【解决方案5】:

        有几种方法:

        1) 创建一个调用相同代码的标准 Windows 应用程序,这样更易​​于运行和调试。这还可以确保您的服务代码不全部在服务中,而是重构为自己的程序集。

        2) 在您的服务器程序文件中,检测服务是否以交互方式运行,并调用服务中的服务方法运行一次。这样,您也可以从 Visual Studio 中运行。 (您需要公开您的服务方法等并创建您的服务实例)

        【讨论】:

          【解决方案6】:

          我认为每个人都提供了很多很好的答案。这将是我调试此问题的有序方法:

          • 检查您的事件日志。
          • 记录所有错误(Log4Net、企业库或仅写入事件日志),尤其是在 Main 方法中使用 try..catch。
          • 编写可以在环境中运行的单元测试。
          • 确保您的 app.config 文件正确。您可能需要将来自不同项目的值合并为一个。
          • 测试数据库连接。 ping 服务器。 Telnet 到端口 1433(如果是默认 SQL Server)。编写一个简单的控制台应用进行测试。
          • 通过附加到进程进行调试。
          • 使用控制台/服务混合方法(很棒的技术,我用来实时输出调试消息)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-10-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多