Консольное приложение .NET как служба Windows

У меня консольное приложение и вы хотите запустить его как службу Windows. VS2010 имеет шаблон проекта, который позволяет подключить консольный проект и создать службу Windows. Я бы не хотел добавлять отдельный сервисный проект и, если возможно, интегрировать код службы в консольное приложение, чтобы консольное приложение использовалось как один проект, который мог запускаться как консольное приложение или как служба Windows, если он запускается, например, из командной строки с помощью переключателей.

Может быть, кто-то может предложить библиотеку classов или fragment кода, который мог бы быстро и легко преобразовать консольное приложение c # в службу?

Обычно я использую следующий techinque для запуска того же приложения, что и консольное приложение или как служба:

public static class Program { #region Nested classes to support running as service public const string ServiceName = "MyService"; public class Service : ServiceBase { public Service() { ServiceName = Program.ServiceName; } protected override void OnStart(string[] args) { Program.Start(args); } protected override void OnStop() { Program.Stop(); } } #endregion static void Main(string[] args) { if (!Environment.UserInteractive) // running as service using (var service = new Service()) ServiceBase.Run(service); else { // running as console app Start(args); Console.WriteLine("Press any key to stop..."); Console.ReadKey(true); Stop(); } } private static void Start(string[] args) { // onstart code here } private static void Stop() { // onstop code here } } 

Environment.UserInteractive обычно применяется для консольного приложения и false для службы. Технически можно запустить службу в интерактивном режиме, чтобы вместо этого вы могли проверить переключатель командной строки.

У меня был большой успех с TopShelf .

TopShelf – это пакет Nuget, который упрощает создание приложений .NET для Windows, которые могут запускаться как консольные приложения или как службы Windows. Вы можете быстро подключать такие события, как ваша служба. Начать и останавливать события, настраивать с помощью кода, например, устанавливать учетную запись, которую он запускает, настраивать зависимости для других служб и настраивать, как она восстанавливается из-за ошибок.

С консоли диспетчера пакетов (Nuget):

Установочный пакет Topshelf

Для начала ознакомьтесь с примерами кода .

Пример:

 HostFactory.Run(x => { x.Service(s => { s.ConstructUsing(name=> new TownCrier()); s.WhenStarted(tc => tc.Start()); s.WhenStopped(tc => tc.Stop()); }); x.RunAsLocalSystem(); x.SetDescription("Sample Topshelf Host"); x.SetDisplayName("Stuff"); x.SetServiceName("stuff"); }); 

TopShelf также позаботится об установке сервиса, что может сэкономить много времени и удалить шаблонный код из вашего решения. Чтобы установить ваш .exe в качестве службы, вы просто выполните из командной строки следующее:

 myservice.exe install -servicename "MyService" -displayname "My Service" -description "This is my service." 

Вам не нужно подключать ServiceInstaller и все такое – TopShelf делает все для вас.

Итак, вот полное пошаговое руководство:

  1. Создайте новый проект консоли (например, MyService)
  2. Добавьте две ссылки библиотек: System.ServiceProcess и System.Configuration.Install
  3. Добавьте три файла, напечатанных ниже
  4. Создайте проект и запустите «InstallUtil.exe c: \ path \ to \ MyService.exe»
  5. Теперь вы должны увидеть MyService в списке услуг (запустите services.msc)

* InstallUtil.exe обычно можно найти здесь: C: \ windows \ Microsoft.NET \ Framework \ v4.0.30319 \ InstallUtil.ex e

Program.cs

 using System; using System.IO; using System.ServiceProcess; namespace MyService { class Program { public const string ServiceName = "MyService"; static void Main(string[] args) { if (Environment.UserInteractive) { // running as console app Start(args); Console.WriteLine("Press any key to stop..."); Console.ReadKey(true); Stop(); } else { // running as service using (var service = new Service()) { ServiceBase.Run(service); } } } public static void Start(string[] args) { File.AppendAllText(@"c:\temp\MyService.txt", String.Format("{0} started{1}", DateTime.Now, Environment.NewLine)); } public static void Stop() { File.AppendAllText(@"c:\temp\MyService.txt", String.Format("{0} stopped{1}", DateTime.Now, Environment.NewLine)); } } } 

MyService.cs

 using System.ServiceProcess; namespace MyService { class Service : ServiceBase { public Service() { ServiceName = Program.ServiceName; } protected override void OnStart(string[] args) { Program.Start(args); } protected override void OnStop() { Program.Stop(); } } } 

MyServiceInstaller.cs

 using System.ComponentModel; using System.Configuration.Install; using System.ServiceProcess; namespace MyService { [RunInstaller(true)] public class MyServiceInstaller : Installer { public MyServiceInstaller() { var spi = new ServiceProcessInstaller(); var si = new ServiceInstaller(); spi.Account = ServiceAccount.LocalSystem; spi.Username = null; spi.Password = null; si.DisplayName = Program.ServiceName; si.ServiceName = Program.ServiceName; si.StartType = ServiceStartMode.Automatic; Installers.Add(spi); Installers.Add(si); } } } 

Вы можете использовать

 reg add HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run /v ServiceName /d "c:\path\to\service\file\exe" 

И он появится в списке услуг. Я не знаю, правильно ли работает. Обычно служба должна прослушивать несколько событий.

Однако существует несколько оболочек служб, которые могут запускать любое приложение в качестве реального сервиса. Для примера Microsoft SrvAny из набора ресурсов Win2003

Я слышал, что вы хотите, чтобы одна assembly остановила повторный код, но это было бы проще и сократить повторение кода и упростить повторное использование вашего кода другими способами в будущем, если … вы разделите его на 3 сборки.

  1. Одна assembly библиотеки, которая выполняет всю работу. Тогда у вас есть два очень тонких / простых проекта:
  2. один из которых является командной строкой
  3. один из которых является службой Windows.

Во-первых, я вставляю решение консольного приложения в решение для Windows и ссылаюсь на него.

Затем я делаю консольное приложение classа программы общедоступным

 ///  /// Hybrid service/console application ///  public class Program { } 

Затем я создаю две функции в консольном приложении

  ///  /// Used to start as a service ///  public void Start() { Main(); } ///  /// Used to stop the service ///  public void Stop() { if (Application.MessageLoop) Application.Exit(); //windows app else Environment.Exit(1); //console app } 

Затем в самой службе windows я создаю экземпляр программы и вызываю функции Start и Stop, добавленные в OnStart и OnStop. Смотри ниже

 class WinService : ServiceBase { readonly Program _application = new Program(); ///  /// The main entry point for the application. ///  static void Main() { ServiceBase[] servicesToRun = { new WinService() }; Run(servicesToRun); } ///  /// Set things in motion so your service can do its work. ///  protected override void OnStart(string[] args) { Thread thread = new Thread(() => _application.Start()); thread.Start(); } ///  /// Stop this service. ///  protected override void OnStop() { Thread thread = new Thread(() => _application.Stop()); thread.Start(); } } 

Этот подход также может использоваться для гибридного приложения windows / windows

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

«сохранить консольное приложение как один проект»

Однажды я был на вашем месте, превратив консольное приложение в сервис. Сначала вам нужен шаблон, если вы работаете с VS Express Edition. Вот ссылка, где вы можете сделать первые шаги: C # Windows Service , это было очень полезно для меня. Затем, используя этот шаблон, добавьте свой код в нужные события службы.

Чтобы улучшить обслуживание, есть еще одна вещь, которую вы можете сделать, но это не быстро и / или легко, использует приложения и создает dll для загрузки / выгрузки. В одном вы можете запустить новый процесс с помощью консольного приложения, а в другой dll вы можете просто добавить функциональность, которую должен выполнить сервис.

Удачи.

Вам нужно разделить функциональность на class или classы и запустить ее через один из двух заглушек. Консольный заглушка или служебная заглушка.

Как видно, при запуске окон многие сервисы, составляющие инфраструктуру, не предоставляют (и не могут напрямую) предоставлять консольные windows пользователю. Служба должна взаимодействовать с пользователем не графически: через SCM; в журнале событий, в некоторый файл журнала и т. д. Службе также необходимо будет связываться с windowsми через SCM, иначе он будет отключен.

Очевидно, было бы приемлемо иметь какое-то консольное приложение, которое может связываться с сервисом, но служба должна запускаться независимо без необходимости взаимодействия с графическим интерфейсом.

Консоль-заглушка может очень полезна для отладки поведения службы, но не должна использоваться в «производственной» среде, которая, в конце концов, является целью создания службы.

Я не читал его полностью, но эта статья, кажется, пинтит в правильном направлении.

  • Невозможно указать модификатор «async» в методе «Основной» консольного приложения
  • Как запустить консольное приложение C # с консолью, скрытой
  • Как запустить консольное приложение из Windows Service?
  • .NET Console TextWriter, который понимает Отступ / Неподвижный / IndentLevel
  • Как распечатать UTF-8 из консольного приложения c ++ в Windows
  • Как мне разрешить ввод номера в мое консольное приложение C #?
  • Как открыть окно консоли
  • Как написать быстрый цветной вывод на консоль?
  • Owin Self host & ASP .Net MVC
  • Какова команда выхода из приложения Console на C #?
  • Давайте будем гением компьютера.