Imports System.ServiceModel Imports System.ServiceProcess Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Database Imports DigitalData.Modules Imports System.ServiceModel.Description Imports DigitalData.Modules.Config Imports System.ServiceModel.Channels Public Class WindowsService Inherits ServiceBase Private ServiceHost As ServiceHost(Of EDMIService) Private LogConfig As LogConfig Private LogConfigScheduler As LogConfig Private Logger As Logger Private Firebird As Firebird Private MSSQL_ECM As MSSQLServer Private MSSQL_IDB As MSSQLServer Private MSSQL_Config As MSSQLServer Private ConfigManager As ConfigManager(Of Config) Private Config As Config Private Filesystem As Filesystem.File Private GlobalState As GlobalState Private Scheduler As Scheduler Public Sub New() ServiceName = SERVICE_NAME End Sub Public Shared Sub Main() Run(New WindowsService()) End Sub Protected Overrides Sub OnStart(args As String()) Try ' Init Dim oServicePath As String = AppDomain.CurrentDomain.BaseDirectory Dim oServiceVersion As String = My.Application.Info.Version.ToString() ' Initializing Logger LogConfig = New LogConfig(LogConfig.PathType.CustomPath, IO.Path.Combine(oServicePath, "Log"), FileKeepRangeInDays:=3) LogConfigScheduler = New LogConfig(LogConfig.PathType.CustomPath, IO.Path.Combine(oServicePath, "Log"), Suffix:="Scheduler", FileKeepRangeInDays:=3) Logger = LogConfig.GetLogger() ' Log Initial Logger.Info("Service [{0}] is starting...", SERVICE_DISPLAY_NAME) Logger.Info("ServiceDirectory: [{0}]", oServicePath) Logger.Info("Version: [{0}]", oServiceVersion) ' Initializing Config Logger.Info("Loading Config") ConfigManager = New ConfigManager(Of Config)(LogConfig, oServicePath) Config = ConfigManager.Config ' Setup Reload-timer for config Dim oTimer As New Timers.Timer(60000) AddHandler oTimer.Elapsed, AddressOf ReloadTimer_Tick oTimer.Start() ' Setting Debug Flag If ConfigManager.Config.Debug Then Logger.Info("Debug Flag is set to TRUE. Logging will be more verbose.") Else Logger.Info("Debug Flag is set to FALSE. Logging will be less verbose.") End If LogConfig.Debug = ConfigManager.Config.Debug LogConfigScheduler.Debug = ConfigManager.Config.Debug Logger.Debug("Connecting to Databases...") Firebird = StartFirebird() MSSQL_ECM = GetMSSQL_ECM(LogConfig) MSSQL_IDB = GetMSSQL_IDB(LogConfig) MSSQL_Config = GetMSSQL_Config(LogConfig) Logger.Debug("Connection to Databases established!") Logger.Debug("Initializing EDMI Functions...") Filesystem = New Filesystem.File(LogConfig) GlobalState = New GlobalState(LogConfig, MSSQL_IDB, MSSQL_ECM) Dim oMSSQLServer = GetMSSQL_Config(LogConfigScheduler) Scheduler = New Scheduler(LogConfigScheduler, oMSSQLServer, GlobalState.TableStore, GlobalState) Logger.Debug("Loading Global Data ...") GlobalState.LoadObjectStores() GlobalState.LoadConnections() GlobalState.LoadDoctypes() GlobalState.LoadClientConfig(Config) Logger.Debug("Starting Scheduler ...") Scheduler.Start() Logger.Debug("Preparing WCF ServiceHost ...") EDMIService.MSSQL_ECM = MSSQL_ECM EDMIService.MSSQL_IDB = MSSQL_IDB EDMIService.Firebird = Firebird EDMIService.LogConfig = LogConfig EDMIService.AppConfig = Config EDMIService.GlobalState = GlobalState EDMIService.Scheduler = Scheduler Logger.Debug("Starting WCF ServiceHost ...") Dim oBaseAddresses() As Uri = {New Uri(SERVICE_BASE_ADDRESS)} ServiceHost = New ServiceHost(Of EDMIService)(oBaseAddresses) ServiceHost.EnableMetadataExchange(False) ' MEX-Endpoints explizit entfernen, da sie Port-Konflikte verursachen Dim oMexEndpoints = ServiceHost.Description.Endpoints _ .Where(Function(e) e.Contract.ContractType = GetType(IMetadataExchange)) _ .ToList() For Each oEndpoint In oMexEndpoints ServiceHost.Description.Endpoints.Remove(oEndpoint) Logger.Debug("OnStart -> Removed MEX endpoint: {0}", oEndpoint.Address.ToString) Next Logger.Debug("Listing Endpoints:") For Each oEndpoint In ServiceHost.Description.Endpoints Logger.Debug("Name: {0}", oEndpoint.Name) Logger.Debug("Address: {0}", oEndpoint.Address.ToString) Logger.Debug("Listen Uri: {0}", oEndpoint.ListenUri.AbsoluteUri) Logger.Debug("Binding: {0}", oEndpoint.Binding.Name) Logger.Debug("Contract: {0}", oEndpoint.Contract.Name) Next Logger.Debug("Starting WFC ServiceHost..") Try ServiceHost.Open() Logger.Debug("WCF ServiceHost started!") Catch ex As System.ServiceModel.AddressAlreadyInUseException Logger.Error("Port is already in use! Check if another instance is running. Details: {0}", ex.Message) GracefullyStop() Catch ex As Exception Logger.Warn("⚠ Unexpected error while opening ServiceHost: {0}", ex.Message) Logger.Error(ex) GracefullyStop() End Try Logger.Info("✔ Service [{0}] started successfully!", SERVICE_DISPLAY_NAME) Catch ex As Exception Logger.Warn("⚠ Unexpected Error while starting the service: {0}", ex.Message) Logger.Error(ex) GracefullyStop() End Try End Sub Private Sub ReloadTimer_Tick() If ConfigManager.Reload() = False Then Logger.Warn("⚠ Could not reload config, check the service and config file.") End If Config = ConfigManager.Config LogConfig.Debug = ConfigManager.Config.Debug End Sub Private Function StartFirebird() As Firebird Logger.Debug("Connecting to Firebird") If Config.Firebird_Datasource = String.Empty Then Logger.Info("Firebird database not configured. Skipping.") Return Nothing End If Try Dim oFirebird = New Firebird( LogConfig, Config.Firebird_Datasource, Config.Firebird_DatabaseName, Config.Firebird_DatabaseUser, Config.Firebird_DatabasePassword ) Logger.Info("Database connection established.") Return oFirebird Catch ex As Exception Logger.Warn("⚠ StartFirebird: Could not connect to firebird database.") Logger.Error(ex) Return Nothing End Try End Function Private Function GetMSSQL_ECM(pLogConfig As LogConfig) As MSSQLServer Logger.Debug("Connecting to ECM MSSQL") If Config.ConnectionString_ECM = String.Empty Then Logger.Warn("⚠ Configuration for ConnectionString_ECM is missing.") Throw New ArgumentNullException("ConnectionString_ECM") End If Dim oMSSQL = New MSSQLServer(pLogConfig, Config.ConnectionString_ECM) Logger.Info("✔ Database connection to ECM Database established.") Return oMSSQL End Function Private Function GetMSSQL_IDB(pLogConfig As LogConfig) As MSSQLServer Logger.Debug("Connecting to IDB MSSQL") If Config.ConnectionString_IDB = String.Empty Then Logger.Warn("⚠ Configuration for ConnectionString_IDB is missing.") Throw New ArgumentNullException("ConnectionString_IDB") End If Dim oMSSQL = New MSSQLServer(pLogConfig, Config.ConnectionString_IDB) Logger.Info("✔ Database connection to IDB Database established.") Return oMSSQL End Function Private Function GetMSSQL_Config(pLogConfig As LogConfig) As MSSQLServer Logger.Debug("Connecting to Config MSSQL...") If Config.ConnectionString_Config = String.Empty Then If Config.ConnectionString_ECM <> String.Empty Then Logger.Debug("Using ConnectionString_ECM for Config Database connection!") Return GetMSSQL_ECM(pLogConfig) Else Logger.Warn("⚠ Configuration for ConnectionString_Config is missing and ConnectionString_ECM is also missing.") Throw New ArgumentNullException("ConnectionString_Config") End If End If Dim oMSSQL = New MSSQLServer(pLogConfig, Config.ConnectionString_Config) Logger.Info("✔ Database connection to Config Database established.") Return oMSSQL End Function Protected Overrides Sub OnStop() GracefullyStop() End Sub Private Sub GracefullyStop() Logger.Info("GracefullyStop - Service {0} is stopping!", SERVICE_DISPLAY_NAME) If ServiceHost IsNot Nothing Then Try If ServiceHost.State = CommunicationState.Faulted Then Logger.Warn("⚠ GracefullyStop - ServiceHost is in Faulted state. Using Abort() instead of Close().") ServiceHost.Abort() Else ServiceHost.Close() End If Catch ex As Exception Logger.Warn("⚠ GracefullyStop - Error while closing ServiceHost: {0}", ex.Message) Logger.Error(ex) ServiceHost.Abort() Finally ServiceHost = Nothing End Try End If If Scheduler IsNot Nothing Then Logger.Info("GracefullyStop - Stopping Scheduler.") Scheduler.Stop() End If End Sub End Class