Služba (Windows Service) je speciální typ aplikace, která v systému může běžet na pozadí bez nutnosti přihlášení uživatele (běžné aplikace běží v relaci přihlášeného uživatele a dědí jeho přístupová oprávnění, služby obvykle běží pod speciálním systémovým účtem s omezenými oprávněními).
Pokud jste někdy psali službu ve Visual Studiu v některém z .NET jazyků, jistě víte, jaké je její ladění příšerný opruz. Běžně se při ladění postupuje tak, že po každé změně assembly služby se musí služba odregistrovat a opětovně zaregistrovat pomocí nástroje .NET Framework Installation Utility (InstallUtil.exe). Potom je možné službu ovládat pomocí správce služeb z Nástrojů pro správu.
K běžící službě se potom připojí z Visual Studia pomocí Tools/Attach to Process a dále se ladí běžným způsobem (zdrojové kódy služby samozřejmě musí být k dispozici). Uvědomte si, že toto je nutné opakovat při každé změně assembly, tedy např. po přidání nebo změně jediného řádku kódu. Krása a jednoduchost nastavení zarážek a stisknutí F5 u služeb standardně prostě není.
Hledal jsem poměrně dlouho, jak co nejvíce zjednodušit tento proces a nejlepší řešení (pro C#) jsem našel na CodeProjectu. Předem upozorňuji, že je nutné zasáhnout do vstupní metody Main v souboru *.Designer.*, což není příliš čisté řešení, ale je to to nejlepší co jsem našel. I v samotné metodě Main vytvořené Studiem je komentář, ze kterého lze vyčíst, že tam je možné provádět změny, takže to není taková prasárna, jako třeba měnit *.Designer.* u formulářů.
'Původní Service1.Designer.vb:
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
' More than one NT Service may run within the same process. To add
' another service to this process, change the following line to
' create a second service object. For example,
'
' ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1, New MySecondUserService}
'
ServicesToRun = New System.ServiceProcess.ServiceBase() {New Service1}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub
'Upravený Service1.Designer.vb:
Shared Sub Main()
#If Not Debug Then
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
ServicesToRun = New System.ServiceProcess.ServiceBase() {New Service1}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
#Else
Dim service As New Service1
service.OnStart(Nothing)
#End If
End Sub
Trik zpočívá v přidání podmíněné kompilace spouštěcí metody služby, která se posléze bude dát spouštět a ladit z Visual Studia tak, jako běžné aplikace bez nutnosti registrování pomocí InstallUtil.exe. Metoda OnStart je v podstatě to, co se bude dít po spuštění služby ve správci služeb (nebo NET START). Protože se jedná o kompilaci podmíněnou nastavením režimu kompilace (Debug nebo Release), nebudete muset provádět žádné změny v assembly určené k produkci.
Nevýhoda tohoto postupu je jenom v tom, že nelze nasimulovat zastavení, pozastavení a opětovné spuštění služby. Pokud ale nemáte toto implementováno a je potřeba ladit především hlavní funkčnost služby, je to naprosto zanedbatelné negativum.