В этой статье хочу рассказать как правильно разместить службу WCF (Windows Communication Foundation) в службе Windows 7.
Создадим новый проект WCF Service Library.
На дизайнере службы нажимаем правую кнопку и добавляем установщик (Add Installer).
Выбираем появившийся serviceProcessInstaller1 и меняет Account с User на LocalSystem
Добавляем в проект WindowsService1 ссылку на проект WcfLibraryService (Add reference)
Выбираем serviceInstaller1, переключаемся на вкладку событий, и дважды щелкаем по событию AfterInstall.
Переходим к коду, добавляем using System.Management;
В процедуру serviceInstaller1_AfterInstall вписываем следующий код:
Это действие позволит службе взаимодействовать с рабочим столом пользователя.
Хотя в Windows 7 это уже не актуально. И только добавляем больше проблем.
Весь код файла выглядит так:
В свойствах проекта WcfServiceLibrary на последней вкладке снимаем галочку Start WCF Service Host.
Копируем файл app.config в проекте WcfServiceLibrary
Этот файл нужно вставить в проект WindowsService
Идея такая, что файл app.config должен быть одинаковый в этих двух проектах.
Потому что служба WCF будет вызываться из службы Windows, то в проекте службы Windows должны находиться параметры WCF службы. Эти параметры служба Windows (WindowsService1) не может достать из файла app.config проекта WcfServiceLibrary.
В проекте WindowsService1 на файле Service1 нажимаем правой кнопкой и выбираем View Code
Добавляем ссылку на сборку System.ServiceModel;
И в коде вписываем using System.ServiceModel;
В процедуре OnStart вписываем код:
Это позволит службе Windows при запуске запустить хостинг WCF службы
В процедуре OnStop вписываем код:
В итоге общий код файла выглядит так:
Добавляем новый проект Windows Forms. И делаем его запускаемым по-умолчанию (Set as Startup project).
Кидаем на форму кнопку и добавляем ссылку на службу (Add Service Reference)
Нажимаем кнопку Discover и выбираем службу Service1
Весь файл должен выглядеть так:
Нажимаем F6 - для компиляции проекта. Ошибок быть не должно.
Открываем папку проекта WindowsService1
В эту папку нужно скопировать файл InstallUtil.exe
Чтобы его найти на вашем компьютере воспользуйтесь поиском.
Создадим файл InstallServiceAndStart.bat со следующим текстом:
InstallUtil.exe WindowsService1.exe
net start Service1
Создадим файл UninstallServiceAndStop.bat со следующим текстом:
net stop Service1
InstallUtil.exe /u WindowsService1.exe
В итоге папка должна выглядеть так:
Если вы используете Windows XP то для запуска/удаления службы можно пользоваться этими BAT файлами. Если же Windows 7 - то нужно сделать так:
В меню найдите пункт Microsoft Visual Studio 2010\Visual Studio tools
В этой папке есть "Open Visual Studio Command Prompt (2010)", нажмите на нем правой кнопкой мыши и выберите "Запуск от имени Администратора". Отобразится та же консоль.
Поменяйте текущую папку.
В этой папке есть "Open Visual Studio Command Prompt (2010)", нажмите на нем правой кнопкой мыши и выберите "Запуск от имени Администратора". Поменяйте текущую папку на папку с файлом WindowsService1.exe. Скопируйте текст из файла
Создадим новый проект WCF Service Library.
В Solution Explorer находим файл app.config, нажимаем на нем правой кнопкой и выбираем Edit WCF Configuration.
Переходим к пункту Host. Выбираем базовый адрес и нажимаем кнопку "Edit"
И вписываем адрес: net.tcp://localhost:8732/Service1/
Должно выглядеть вот так:
На пункте Binding нажимаем правую кнопку и выбираем New Binding Configuration
Далее выбираем netTcpBinding
Переходим к пункту serviceMetadata и меняем значение HttpGetEnabled на False.
Переходим к пункту Service Endpoint и меняет Binding на netTcpBinding
В BindingConfiguration ставим NewBinding0
Переходим ко второму пункту (Empty Name) и в Binding указываем mexTcpBinding
На этом настройка конфигурации закончена. Нажимаем File - Save.
В проект добавляем службу Windows.
Выбираем появившийся serviceProcessInstaller1 и меняет Account с User на LocalSystem
Добавляем в проект WindowsService1 ссылку на проект WcfLibraryService (Add reference)
Выбираем serviceInstaller1, переключаемся на вкладку событий, и дважды щелкаем по событию AfterInstall.
Переходим к коду, добавляем using System.Management;
В процедуру serviceInstaller1_AfterInstall вписываем следующий код:
Code Snippet
- private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
- {
- ConnectionOptions coOptions = new ConnectionOptions();
- coOptions.Impersonation = ImpersonationLevel.Impersonate;
- ManagementScope mgmtScope = new System.Management.ManagementScope(@"root\CIMV2", coOptions);
- mgmtScope.Connect();
- using (ManagementObject wmiService = new ManagementObject("Win32_Service.Name='" + serviceInstaller1.ServiceName + "'"))
- {
- ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
- InParam["DesktopInteract"] = true;
- wmiService.InvokeMethod("Change", InParam, null);
- }
- }
Это действие позволит службе взаимодействовать с рабочим столом пользователя.
Хотя в Windows 7 это уже не актуально. И только добавляем больше проблем.
Весь код файла выглядит так:
Code Snippet
- using System.ComponentModel;
- using System.Configuration.Install;
- using System.Management;
- namespace WindowsService1
- {
- [RunInstaller(true)]
- public partial class ProjectInstaller : System.Configuration.Install.Installer
- {
- public ProjectInstaller()
- {
- InitializeComponent();
- }
- private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
- {
- ConnectionOptions coOptions = new ConnectionOptions();
- coOptions.Impersonation = ImpersonationLevel.Impersonate;
- ManagementScope mgmtScope = new System.Management.ManagementScope(@"root\CIMV2", coOptions);
- mgmtScope.Connect();
- using (ManagementObject wmiService = new ManagementObject("Win32_Service.Name='" + serviceInstaller1.ServiceName + "'"))
- {
- ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
- InParam["DesktopInteract"] = true;
- wmiService.InvokeMethod("Change", InParam, null);
- }
- }
- }
- }
В свойствах проекта WcfServiceLibrary на последней вкладке снимаем галочку Start WCF Service Host.
Копируем файл app.config в проекте WcfServiceLibrary
Этот файл нужно вставить в проект WindowsService
Идея такая, что файл app.config должен быть одинаковый в этих двух проектах.
Потому что служба WCF будет вызываться из службы Windows, то в проекте службы Windows должны находиться параметры WCF службы. Эти параметры служба Windows (WindowsService1) не может достать из файла app.config проекта WcfServiceLibrary.
В проекте WindowsService1 на файле Service1 нажимаем правой кнопкой и выбираем View Code
Добавляем ссылку на сборку System.ServiceModel;
И в коде вписываем using System.ServiceModel;
В процедуре OnStart вписываем код:
Code Snippet
- protected override void OnStart(string[] args)
- {
- if (myServiceHost != null)
- {
- if (myServiceHost.State == CommunicationState.Opened) myServiceHost.Close();
- }
- try
- {
- myServiceHost = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
- myServiceHost.Open();
- }
- catch (Exception ex)
- {
- EventLog.WriteEntry(this.ServiceName, ex.Message);
- }
- }
Это позволит службе Windows при запуске запустить хостинг WCF службы
В процедуре OnStop вписываем код:
Code Snippet
- protected override void OnStop()
- {
- if (myServiceHost != null)
- {
- myServiceHost.Close();
- myServiceHost = null;
- }
- }
В итоге общий код файла выглядит так:
Code Snippet
- using System;
- using System.Diagnostics;
- using System.ServiceProcess;
- using System.ServiceModel;
- namespace WindowsService1
- {
- public partial class Service1 : ServiceBase
- {
- public Service1()
- {
- InitializeComponent();
- }
- private static ServiceHost myServiceHost = null;
- protected override void OnStart(string[] args)
- {
- if (myServiceHost != null)
- {
- if (myServiceHost.State == CommunicationState.Opened) myServiceHost.Close();
- }
- try
- {
- myServiceHost = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
- myServiceHost.Open();
- }
- catch (Exception ex)
- {
- EventLog.WriteEntry(this.ServiceName, ex.Message);
- }
- }
- protected override void OnStop()
- {
- if (myServiceHost != null)
- {
- myServiceHost.Close();
- myServiceHost = null;
- }
- }
- }
- }
Добавляем новый проект Windows Forms. И делаем его запускаемым по-умолчанию (Set as Startup project).
Кидаем на форму кнопку и добавляем ссылку на службу (Add Service Reference)
Нажимаем кнопку Discover и выбираем службу Service1
В обработчик нажатия на кнопку вписываем код:
Code Snippet
- private void button1_Click(object sender, EventArgs e)
- {
- ServiceReference1.Service1Client myService = new ServiceReference1.Service1Client();
- MessageBox.Show(myService.GetData(123), "My Service");
- myService.Close();
- }
Весь файл должен выглядеть так:
Code Snippet
- using System;
- using System.Windows.Forms;
- namespace WindowsFormsApplication1
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private void button1_Click(object sender, EventArgs e)
- {
- ServiceReference1.Service1Client myService = new ServiceReference1.Service1Client();
- MessageBox.Show(myService.GetData(123), "My Service");
- myService.Close();
- }
- }
- }
Нажимаем F6 - для компиляции проекта. Ошибок быть не должно.
Открываем папку проекта WindowsService1
В эту папку нужно скопировать файл InstallUtil.exe
Чтобы его найти на вашем компьютере воспользуйтесь поиском.
Создадим файл InstallServiceAndStart.bat со следующим текстом:
InstallUtil.exe WindowsService1.exe
net start Service1
Создадим файл UninstallServiceAndStop.bat со следующим текстом:
net stop Service1
InstallUtil.exe /u WindowsService1.exe
В итоге папка должна выглядеть так:
Если вы используете Windows XP то для запуска/удаления службы можно пользоваться этими BAT файлами. Если же Windows 7 - то нужно сделать так:
В меню найдите пункт Microsoft Visual Studio 2010\Visual Studio tools
В этой папке есть "Open Visual Studio Command Prompt (2010)", нажмите на нем правой кнопкой мыши и выберите "Запуск от имени Администратора". Отобразится та же консоль.
Поменяйте текущую папку.
Для установки и запуска службы скопируйте содержимое файла InstallServiceAndStart.bat и вставьте в это окно и нажмите Enter (для Windows 7). Если в Windows 7 запускать файлы, то после каждого удаления службы Windows придется перезагружать компьютер.
Если у вас Windows XP то можно просто запускать батники.
Служба установлена и запущена.
Теперь нужно запустить приложение WindowsFormsApplication1. Возможно что Visual Studio не позволит запустить отладку, т.к.он не сможет заменить файл WindowsService1.exe потому, что он будет выполняться ОС. Я просто открыл папку и запустил WindowsFormsApplication1.exe
Нажимаем кнопку и через несколько секунд получаем сообщение
Это говорит о том, что наша служба Windows работает.
Если в службу вносите изменения то нужно произвести удаление службы.
Для этого в Windows XP просто запустите UninstallServiceAndStop.bat в Windows 7 нужно найти пункт Microsoft Visual Studio 2010\Visual Studio tools
В этой папке есть "Open Visual Studio Command Prompt (2010)", нажмите на нем правой кнопкой мыши и выберите "Запуск от имени Администратора". Поменяйте текущую папку на папку с файлом WindowsService1.exe. Скопируйте текст из файла
Комментариев нет:
Отправить комментарий