Запуск службы Windows в режиме консоли? - PullRequest
30 голосов
/ 20 мая 2011

Я нашел пример кода, размещенного на https://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/4d45e9ea5471cba4/4519371a77ed4a74?hl=en&pli=1 для самостоятельной установки службы Windows.Я в C # на FX 4.0.Пытаясь выяснить, где я сошел с рельсов ...

Мои вопросы:

  1. Я создал проект Win Service.В program.cs / main () я в значительной степени скопировал пример кода.Похоже, что почти все работает , за исключением , запускающего окно консоли, если я нахожусь в режиме отладки (конечно, с передачей - c).По некоторым причинам окно консоли никогда не открывается.
  2. Другая проблема, с которой я столкнулся, был вызов StartUp () / ShutDown () в части консоли не будет компилироваться.В итоге мне пришлось инициализировать мой сервисный объект и затем вызвать его.
  3. Я получаю следующую ошибку при вызове метода Console.ReadKey ():

Невозможночитать ключи, когда у любого приложения нет консоли или когда ввод с консоли был перенаправлен из файла.Попробуйте Console.Read.

Мой код и прочее:

Изображение структуры моего проекта:

http://screencast.com/t/zVjqkmoED

ПРИМЕЧАНИЕ: Ядублировал последовательность запуска в TestHarness в режиме отладки.Если / когда я получу эту работу, я исключу это из решения.Проект Библиотеки - это место, где живет большая часть моего кода.

PROGRAM.CS

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ComponentModel;
using System.Configuration.Install;
using System.Collections;
using RivWorks.FeedHandler.Service;

namespace RivWorks.FeedHandler
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static int Main(string[] args)
        {
            bool install = false, uninstall = false, console = false, rethrow = false;

            try
            {
                foreach (string arg in args)
                {
                    switch (arg)
                    {
                        case "-i":
                        case "-install":
                            install = true; break;
                        case "-u":
                        case "-uninstall":
                            uninstall = true; break;
                        case "-c":
                        case "-console":
                            console = true; break;
                        default:
                            Console.Error.WriteLine("Argument not expected: " + arg);
                            break;
                    }
                }
                if (uninstall)
                {
                    Install(true, args);
                }
                if (install)
                {
                    Install(false, args);
                }
                if (console)
                {
                    Console.WriteLine("Starting...");
                    FeedListener fl = new FeedListener();
                    fl.StartUp();
                    Console.WriteLine("System running; press any key to stop");
                    Console.ReadKey(true);
                    fl.ShutDown();
                    Console.WriteLine("System stopped");
                }
                else if (!(install || uninstall))
                {
                    rethrow = true; // so that windows sees error...
                    ServiceBase[] services = { new Service.FeedListener() };
                    ServiceBase.Run(services);
                    rethrow = false;
                }
                return 0;
            }
            catch (Exception ex)
            {
                if (rethrow) throw;
                Console.Error.WriteLine(ex.Message);
                return -1;
            }
        }
        static void Install(bool undo, string[] args)
        {
            try
            {
                Console.WriteLine(undo ? "uninstalling" : "installing");
                using (AssemblyInstaller inst = new AssemblyInstaller(typeof(Program).Assembly, args))
                {
                    IDictionary state = new Hashtable();
                    inst.UseNewContext = true;
                    try
                    {
                        if (undo)
                        {
                            inst.Uninstall(state);
                        }
                        else
                        {
                            inst.Install(state);
                            inst.Commit(state);
                        }
                    }
                    catch
                    {
                        try
                        {
                            inst.Rollback(state);
                        }
                        catch { }
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
            }
        }
    }


    [RunInstaller(true)]
    public sealed class MyServiceInstallerProcess : ServiceProcessInstaller
    {
        public MyServiceInstallerProcess()
        {
            this.Account = ServiceAccount.NetworkService;
        }
    }

    [RunInstaller(true)]
    public sealed class MyServiceInstaller : ServiceInstaller
    {
        public MyServiceInstaller()
        {
            this.Description = "Provides a service to listen for, then import, feed files from various sources.";
            this.DisplayName = "RIVWorks Feed Handler (.NET 4.0)";
            this.ServiceName = "FeedListener";
            this.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
        }
    }
}

FEEDLISTENER.CS

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
using sysIO = System.IO;
using RivWorks.FeedHandler;
using System.Collections;
using RivWorks.FeedHandler.Library;
using System.Threading;

namespace RivWorks.FeedHandler.Service
{
    public partial class FeedListener : ServiceBase
    {
        #region Declarations
        static private List<string> _keys = new List<string>();
        static private System.Threading.Timer _clock = null;
        static private FileSystemWatcher _watcher;
        static private RivWorks.FeedHandler.Library.QueueHandler _qHandler = null;
        static private bool _isDequeueing = false;
        #endregion

        #region Constructor
        public FeedListener()
        {
            InitializeComponent();
        }
        #endregion

        #region Internal Methods
        internal void StartUp() {...}
        internal void ShutDown() {...}
        #endregion

        #region Start/Stop
        protected override void OnStart(string[] args)
        {
            StartUp();
        }
        protected override void OnStop()
        {
            ShutDown();
        }
        #endregion

        #region Event Handlers
        static void qHandler_QueuesGrew() {...}
        static void qHandler_QueuesShrunk() {...}
        static void qHandler_QueuesChanged() {...}
        static void fileCreatedOrChanged(object sender, sysIO.FileSystemEventArgs e) {...}
        #endregion

        #region Private Methods
        private static void Tick(object state) {...}
        private static void WriteToEventLog(Exception ex, EventLogEntryType eventLogEntryType) {...}
        private static void WriteToEventLog(string message, EventLogEntryType eventLogEntryType) {...}
        #endregion
    }
}

Ответы [ 3 ]

66 голосов
/ 20 мая 2011

И я нашел свой ответ!Свойства моего проекта были установлены на Windows App вместо Консольное приложение .DOH!(Свойства проекта> Вкладка «Приложение»> Тип вывода:)

1 голос
/ 05 мая 2016

Также ... вместо использования -console arg вы можете идентифицировать его консоль с помощью Environment.UserInteractive, которая будет иметь значение false при запуске в качестве службы, но true при запуске EXE-файла напрямую.

0 голосов
/ 17 сентября 2013

Вы также можете взглянуть на это: http://www.thedavejay.com/2012/04/self-installing-c-windows-service-safe.html

Это позволяет отлаживать как консольное приложение и устанавливать то же приложение, что и служба Windows, без необходимости изменения типа проекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...