简体   繁体   中英

My windows service installed incorrectly?

I have a windows service, the OnStart method contains an application that was not started. I added

System.Diagnostics.Debugger.Launch();

inside the OnStart() and stepped into the code.

protected override void OnStart(string[] args)
    { 
        System.Diagnostics.Debugger.Launch();
        System.Timers.Timer aTimer = new System.Timers.Timer(500); //500 MilliSeconds
        // Hook up the Elapsed event for the timer.
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        // Set the Interval to 2 seconds (2000 milliseconds).
        //aTimer.Interval = 600000;  //10 minutes //2000; //2 seconds (2000 mili seconds)
        aTimer.AutoReset = false;
        aTimer.Enabled = true;
        // Keep the timer alive until the end of Main.  This allows OnStart to close in a timely fashion.
        GC.KeepAlive(aTimer);

    }

    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        IvrApplication.Start();// The code didn't reach here.
    }

IvrApplication.Start() was not executed at all. So I assume my installation is incorrectly.

My installation code:

[MTAThread]
    static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            if (IsInstalled() && !Environment.UserInteractive)
            {
                // Run your service normally.
                ServiceBase[] ServicesToRun = new ServiceBase[] { new IvrService() };
                ServiceBase.Run(ServicesToRun);
            }
            else
            {
                if (Environment.UserInteractive)
                    Console.WriteLine("Debug the service only.");
                if (!IsInstalled())
                    Console.WriteLine("Service is not installed..");
                if (svcPath.ToLower() != "services.exe")
                {
                    // In an interactive session.
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new IvrInteractive());
                    return;
                }
            }
        }
        else if (args.Length == 1)
        {
            switch (args[0])
            {
                case "-install":
                    InstallService();
                    // Here to install the service.
                    break;
                case "-uninstall":
                    StopService();
                    UninstallService();
                    break;

As for InstallService, we have:

    public static bool  InstallService(string svcPath, string svcName, string svcDispName)
    {
        #region Constants declaration.
        int SC_MANAGER_CREATE_SERVICE = 0x0002;
        int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
        //int SERVICE_DEMAND_START = 0x00000003;
        int SERVICE_ERROR_NORMAL = 0x00000001;
        int STANDARD_RIGHTS_REQUIRED = 0xF0000;
        int SERVICE_QUERY_CONFIG = 0x0001;
        int SERVICE_CHANGE_CONFIG = 0x0002;
        int SERVICE_QUERY_STATUS = 0x0004;
        int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
        int SERVICE_START = 0x0010;
        int SERVICE_STOP = 0x0020;
        int SERVICE_PAUSE_CONTINUE = 0x0040;
        int SERVICE_INTERROGATE = 0x0080;
        int SERVICE_USER_DEFINED_CONTROL = 0x0100;
        int SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
        SERVICE_QUERY_CONFIG |
        SERVICE_CHANGE_CONFIG |
        SERVICE_QUERY_STATUS |
        SERVICE_ENUMERATE_DEPENDENTS |
        SERVICE_START |
        SERVICE_STOP |
        SERVICE_PAUSE_CONTINUE |
        SERVICE_INTERROGATE |
        SERVICE_USER_DEFINED_CONTROL);
        int SERVICE_AUTO_START = 0x00000002;
        #endregion Constants declaration.
        try
        {
            IntPtr sc_handle = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
            if (sc_handle.ToInt32() != 0)
            {
                IntPtr sv_handle = CreateService(sc_handle, svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, svcPath, null, 0, null, null, null);
                if (sv_handle.ToInt32() == 0)
                {
                    CloseServiceHandle(sc_handle);
                    return false;
                }
                else
                {
                    //now trying to start the service
                    int i = StartService(sv_handle, 0, null);
                    // If the value i is zero, then there was an error starting the service.
                    // note: error may arise if the service is already running or some other problem.
                    if (i == 0)
                    {
                        Console.WriteLine("Couldnt start service");
                        return false;
                    }
                    Console.WriteLine("Service started successfully");
                    CloseServiceHandle(sc_handle);
                    return true;
                }
            }
            else
            {
                Console.WriteLine("SCM not opened successfully");
                return false;
            }
        }
        catch (Exception e)
        {
            throw e;
        }
    }

You are using GC.KeepAlive method incorrectly.

References the specified object, which makes it ineligible for garbage collection from the start of the current routine to the point where this method is called .

http://msdn.microsoft.com/en-us/library/system.gc.keepalive%28v=vs.110%29.aspx

Just declare aTimer as a field of your windows service class and don't use GC.KeepAlive.

I found the issue. My code is right, just something else. I forgot set the project type as windows service.

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