Я запущу с примера: веб-сервер Apache (в соответствии с Windows) имеет хорошую функцию: это может быть оба выполнено как автономное приложение (с текущими пользовательскими полномочиями), и что это может быть установлено и выполнено как сервис окон непосредственно (как локальная системная учетная запись), с помощью того же исполняемого файла.
Для приложения, которое будет выполнено как автономное приложение, все, что это должно сделать, вроде наличия статического общедоступного Основного () в некотором общедоступном классе.
Для приложения, чтобы быть устанавливаемым и выполнимым как сервис, это должно реализовать классы ServiceBase и Установщика определенным способом. Но, если приложение как это будет запущено как автономное приложение, то оно покажет окно сообщения.
Как этот подобный апачу режим работы может быть достигнут? Я полагаю, что решение просто, но у меня действительно нет идеи, где запустить.
Часть кода, который следует, используется для вызова сервиса. Это может быть изменено для разрешения автономного использования?
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service() // defined elsewhere as Service : ServiceBase
};
ServiceBase.Run(ServicesToRun);
}
}
Мой предпочтительный язык является C#.
Править: В настоящее время я абстрагировал общий код в отдельный блок (давайте назовем его Library.dll), и у меня есть два исполняемых файла: Console.exe и Service.exe, который автономен и сервисные приложения окон, соответственно, и оба - просто средства для вызова Library.dll.
Моя цель состоит в том, чтобы объединить те два исполняемых файла в один, который будет все еще звонить в Library.dll.
Покопавшись, я наконец заглянул под капот .NET (метод System.ServiceProcess.ServiceBase.Run) и обнаружил, что он проверяет Environment.UserInteractive
bool до убедитесь, что исполняемый файл НЕ запускается в интерактивном режиме.
Излишне упрощенное решение, которое у меня работает:
class Program
{
static void Main(string[] args)
{
if (!Environment.UserInteractive)
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
// Service.OnStart() creates instance of MainLib()
// and then calls its MainLib.Start() method
new Service()
};
ServiceBase.Run(ServicesToRun);
return;
}
// Run in a console window
MainLib lib = new MainLib();
lib.Start();
// ...
}
}
В C # простой способ сделать это - потребовать аргумент командной строки, чтобы запустить его как службу. Если аргумента нет, запустите приложение формы / консоли. Затем просто попросите ваш установщик включить аргумент в путь к исполняемому файлу при установке службы, чтобы он выглядел так:
C:\MyApp\MyApp.exe -service
Это будет выглядеть примерно так:
static void Main(string[] args)
{
foreach (string arg in args)
{
//Run as a service if our argument is there
if (arg.ToLower() == "-service")
{
ServiceBase[] servicesToRun = new ServiceBase[] { new Service1() };
ServiceBase.Run(servicesToRun);
return;
}
}
//Run the main form if the argument isn't present, like when a user opens the app from Explorer.
Application.Run(new Form1());
}
Это просто пример, чтобы дать вам представление, возможно, есть более чистые способы написать этот код.
В примере, который вы размещаете, я почти уверен, что приложение Apache написано на C или C ++. Для этого вам понадобится функция ServiceMain. Если вы выполняете его как обычную программу, вызывается main. Если вы укажете на него диспетчер управления службами, вместо этого будет вызван ServiceMain.
Что касается C #, не могу сказать, что знаю об этом. Если бы мне пришлось написать службу на C #, я бы начал здесь - http://msdn.microsoft.com/en-us/library/bb483064.aspx
Вы действительно должны абстрагировать всю свою функциональность в библиотеке. Тот факт, что он запускается из службы Windows, не имеет значения. Фактически, если у вас есть класс ServiceFrontEnd, у которого есть Start () и Stop (), приложение Windows Service могло бы это вызвать, а также приложение командной строки, приложение Windows или что-то еще.
То, что вы здесь описываете, требует большей абстракции. Функциональность «службы» не обязательно должна быть тесно связана с тем, как работает служба Windows. надеюсь, что это поможет