简体   繁体   中英

Problem with testing a Windows service

I want to make a Windows service that will access my database. My database is SQL Server 2005.

Actually I am working on a website and my database is inside our server. I need to access my database every second and update the records. For that purpose I need to make a Windows service that will install into our server and perform the task.

I have been accessing the database from my local machine and then running the service, but problem is I'm not sure how I can test this service.

I tried to install into my local machine. It installed and then I ran the service but it did not perform the task and I think service is not able to connect with the database.

There is no problem in the service nor its installer. The only issue is how to test my Windows service.

You can always create a service / console app hybrid, and use the console app for testing purposes.

What you need to do is something like this - in your program.cs , change the Main method to either run the service, or optionally run as a console app:

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);
        }
    }

and then on your service class, which inherits from ServiceBase and has the OnStart and OnStop , add the RunConsole method like so:

    public void RunConsole(string[] args)
    {
        OnStart(args);

        Console.WriteLine("Service running ... press <ENTER> to stop");

        //Console.ReadLine();
        while (true)
        { }

        OnStop();
    }

Now if you want to run the app to test its functionality, just launch the EXE with a -console command line parameter, and put a breakpoint in the RunConsole method.

You can attach the visual studio solution to the windows service application. Then you can debug the windows service as you do a normal project.

Debug --> Attach to process.

The answer by marc_s is perfect, but for the fact that the service's main thread does not get paused awaiting user input as intended. I think this is why he put in an infinite loop.

Borrowing from Igal Serban's code for creating a console, here's an enhancement of the RunConsole() method that does pause:

    [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();
    }

Use a logger to report errors !

Try catch every possible error and log them in a file and/or better send an email : remember "no one hears a service dying" !

Log4Net has logger to handle rolling files, dabatase persistence and even SMTP message. For example, see : http://logging.apache.org/log4net/release/config-examples.html You'll have probably to check the log file for errors quite regularly. To avoid this kind of chore, I often use the SMTP appender.

Cheers, B.

There are a couple of ways:

1) Create a standard windows app that calls the same code, this is easier to run and debug. This also ensures your service code is not all within the service but refactored out to its own assembly.

2) In your Server Program file, detect if the service is run interatively and call the service methods within the service to run once. This way you can also just run from Visual Studio. (you will need to make your service methods etc public and create an in stance of your service)

I think everyone has provide a lot of great answers. This would be my ordered approach to debugging this issue:

  • Check your event log.
  • Log all errors (Log4Net, Enterprise Library, or just write to Event Log), especially have a try..catch in your Main method.
  • Write a unit tests that you can run in the environment.
  • Ensure your app.config file is correct. You may need to merge values from different projects into one.
  • Test database connectivity. Ping the server. Telnet to port 1433 (if default SQL Server). Write a simple console app to test.
  • Debug by attaching to process.
  • Use the console / service hybrid approach (great technique and I use to stream out debug messages in real-time).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM