none
Changing a Command Line Application to a Windows Service, and confusion about static methods RRS feed

  • Question

  • I've been working on a command line .Net application, and I decided it would work better as a Windows Service.

    So I firstly followed this article and made a simple Windows Service with an EventLog and a Timer: docs.microsoft.com/en-us/dotnet/framework/windows-services/walkthrough-creating-a-windows-service-application-in-the-component-designer

    Then I added a project to my solution using the .Net Windows Service template, and I set it up with an EventLog and a Timer, just like in the simple example in the article. Then I copied most of the code from the original application's main() function into the service's OnTimer() method, along with all the additional methods that were called from that code, and I was pleasantly surprised at how few problems I encountered. 

    I do have one outstanding problem, however. My OnTimer() method starts with this line:

    eventLogMyService.WriteEntry("MyService running hourly checks...", EventLogEntryType.Information, eventId++);

    This code runs happily, but I have a method that logs any output to the console and also to a log file that is sent by FTP and emailed on completion of the program, and I would like to add some code to this method so this output can also be written to the eventLog as well. The method looks like this:

    static void LogResult(string strResult) 
            {
                eventLogMyService.WriteEntry(strResult, EventLogEntryType.Information, eventId++); //  <= CS0120 Error on this line
                Console.WriteLine(strResult);
                sbResults.AppendLine(strResult);
            } 

    But this code won't compile, and raises the following error:

    CS0120  C# An object reference is required for the non-static field, method, or property

    It's complaining about both eventLogMyService and the eventId.

    If I remove static from the method, then those error disappear but I get a whole bunch of other errors. This leads me to realise that while I understand in theory what the word static means (i.e. that something that is static works on the class rather than an instantiated object of that class), I don't really understand how that relates to what I'm doing here.

    Can anyone point me in the right direction?

    Thanks. :-)


    • Edited by PaulCutcliffe Tuesday, July 30, 2019 8:26 PM Improved title
    Tuesday, July 30, 2019 8:25 PM

All replies

  • Hello,

    How is eventid declared?


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange


    Tuesday, July 30, 2019 9:25 PM
    Moderator
  • First you need to understand the this pointer. When an instance of a class is created (allocated/declared) the this pointer points to the instance. Every non-static method in the class has an invisible (internal) parameter that is the this pointer. Then during execution the machine code uses the this pointer to address the members of the class.

    Static methods do not have a this pointer. That is why the Main method of a console program is static; when the program starts, there is no instance of the Program class. Also, when you use the Windows API (using DLLImport), callbacks must be static since the Windows API does not create or understand C# (or C++) classes.

    So when a method is static it does not know where the instance of the class is. A static method must have some other way to find the instance. I hope you can find more on the subject but I hope this is enough to get you started.

    Another hint: search for help using the error message, such as CS0120 - MSDN Search.



    Sam Hobbs
    SimpleSamples.Info


    • Edited by Simple Samples Tuesday, July 30, 2019 10:55 PM website bug
    Tuesday, July 30, 2019 10:54 PM
  • Hi  PaulCutcliffe,

    Thank you for posting here.

    >>If I remove static from the method, then those error disappear but I get a whole bunch of other errors.

    I want to know what errors you get after you remove the static. These errors are generated at compile time or generated at runtime?

    I find the following link may be similar to your problem, you could have a look.

    https://stackoverflow.com/questions/498400/cs0120-an-object-reference-is-required-for-the-nonstatic-field-method-or-prop

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, July 31, 2019 5:38 AM
    Moderator
  • When I posted my question, it was declared at the start of the class, like this:

    private int eventId;

    But then I found I lost one of the errors if I added static like this:

    private static int eventId;

    Then I realised that if I could only do the same with the eventLogMyService, but when I tried I kept getting errors like this: CS0229  C# Ambiguity between eventLogMyService and eventLogMyService, which seemed to make no sense since I had only declared it once. Then I wondered how come it hadn't been declared before.

    But then I found it in the Designer for my MyService.cs file, which I had never used or seen before, other than when I followed the instructions in that article and it told me to add an EventLog from the Components section of the Toolbox, but I don't really understand what that was all about.

    So it seems that through the designer, I've already added a non-static EventLog object which prevents me from having a static one that I can use in my static methods.

    Does that sound about right? And is there a way around this? Thanks.


    Wednesday, July 31, 2019 7:58 AM
  • Okay, so I just deleted the eventLogMyService component from the designer, and added the following lines to the top of the class:

    private static int eventId;

    private static EventLog eventLogMyService;

    ... then these lines to the top of the public MyService() section:

    eventId = 1;
    eventLogMyService = new EventLog();

    ... and now it compiles just fine! :-)

    And I've just run it and it does everything I hoped it would, including logging all the output to the event log, and sending the log via email and FTP! :-)

    Wednesday, July 31, 2019 8:11 AM
  • I get the impression you still do not understand what static means. You seem to be programming using trial-and-error. That won't work; eventually you will be unable to guess at a solution.

    The important thing to understand about static in the context of this previous reply is that when you make a variable static there is only one instance of it for all instances of the class. If you have only one instance of the class then there is no problem but if you have multiple instances and you change the value then that value is the current value for all instances. If you do not understand that then it will cause you problems in the future, it will compile but then you will get unexpected errors during execution and then you will ask for help and people trying to help will spend unnecessary time trying to help.



    Sam Hobbs
    SimpleSamples.Info

    Wednesday, July 31, 2019 7:21 PM