diff --git a/EgwMultiEngineManager.Console/Constants/ConstIni.vb b/EgwMultiEngineManager.Console/Constants/ConstIni.vb new file mode 100644 index 0000000..9d44097 --- /dev/null +++ b/EgwMultiEngineManager.Console/Constants/ConstIni.vb @@ -0,0 +1,23 @@ +'---------------------------------------------------------------------------- +' EgalTech 2015-2024 +'---------------------------------------------------------------------------- +' File : ConstIni.vb Data : 08.05.24 Versione : 2.6e1 +' Contenuto : Modulo costanti sezione e chiavi per file Ini. +' +' +' +' Modifiche : 08.05.24 ES Creazione modulo. +' +' +'---------------------------------------------------------------------------- +Module ConstIni + + Public Const INI_FILE_NAME As String = "Effector.Plugin.FiveLakes.ini" + + Public Const S_GENERAL As String = "General" + Public Const K_CAMEXEPATH As String = "CAMExePath" + Public Const K_MAINPIPELUA As String = "MainPipeLua" + Public Const K_REDISCONNECTION As String = "RedisConnection" + Public Const K_MAXCAMINSTANCES As String = "MaxCAMInstances" + +End Module diff --git a/EgwMultiEngineManager.Console/EgwMultiEngineManager.Console.vbproj b/EgwMultiEngineManager.Console/EgwMultiEngineManager.Console.vbproj index 9b9a3a1..8c770a2 100644 --- a/EgwMultiEngineManager.Console/EgwMultiEngineManager.Console.vbproj +++ b/EgwMultiEngineManager.Console/EgwMultiEngineManager.Console.vbproj @@ -113,6 +113,7 @@ + @@ -129,6 +130,8 @@ Settings.settings True + + @@ -166,4 +169,7 @@ + + copy $(TargetPath) c:\EgtProg\EgwMultiEngineManager\EgwMultiEngineManagerConsole.exe + \ No newline at end of file diff --git a/EgwMultiEngineManager.Console/MainModule.vb b/EgwMultiEngineManager.Console/MainModule.vb index bb14479..9b4ec9d 100644 --- a/EgwMultiEngineManager.Console/MainModule.vb +++ b/EgwMultiEngineManager.Console/MainModule.vb @@ -1,12 +1,18 @@ -Imports System.IO -Imports EgwMultiEngineManager.ExecProcessManager +Imports EgwMultiEngineManager.ExecProcessManager Imports Newtonsoft.Json -Imports Pipelines.Sockets.Unofficial.SocketConnection Imports StackExchange.Redis Module MainModule - Private m_bDebug As Boolean = False + Private Const Chn_EgwEngineInput As String = "EgwEngineInput" + Private Const Chn_EgwEngineOutput As String = "EgwEngineOutput" + + Private m_sDataRoot As String = String.Empty + Friend ReadOnly Property sDataRoot As String + Get + Return m_sDataRoot + End Get + End Property Private m_ExecProcessManager As ExecProcessManager @@ -20,63 +26,47 @@ Module MainModule End Get End Property - Private InputChn As New RedisChannel("EgwEngineInput", RedisChannel.PatternMode.Auto) - Private OutputChn As New RedisChannel("EgwEngineOutput", RedisChannel.PatternMode.Auto) + Private OutputChn As New RedisChannel(Chn_EgwEngineOutput, RedisChannel.PatternMode.Auto) Sub Main() - If IsNothing(m_ExecProcessManager) Then - Dim sCamExePath As String = "c:\EgtProg\EgtEngine\EgtEngineR32.exe" - Dim sMainLuaPath As String = "c:\Temp\EgwMultiEngineManager\Pipe.lua" - m_ExecProcessManager = New ExecProcessManager(sCamExePath, sMainLuaPath, 1, ReturnModes.EVENT_) - m_ExecProcessManager.StartExecutionThread() - AddHandler m_ExecProcessManager.m_AnswerReceived, AddressOf ExecProcessManager_AnswerReceived - End If - Dim sConnection As String = "redis.ufficio:26379, serviceName=devel, DefaultDatabase=6, keepAlive=180, connectTimeout=15000, syncTimeout=15000, asyncTimeout=15000, abortConnect=false, ssl=false, allowAdmin=true" - m_RedisManager = New RedisManager(sConnection, 1) - m_RedisManager.SubscribeChannel("EgwEngineInput", AddressOf EgwEngineInputHandler) - - 'Dim sRettad As String = System.Console.ReadLine() - - ' funzionamento simulato - If m_bDebug Then - m_RedisManager.SubscribeChannel("EgwEngineOutput", AddressOf EgwEngineOutputHandler) - Dim sRead As String = System.Console.ReadLine() - While Not String.IsNullOrWhiteSpace(sRead) - ' passo dati per esecuzione - Dim Args As New Dictionary(Of String, String) - Dim ReadFile As String = File.ReadAllText("c:\Temp\EgwMultiEngineManager\AntaSingola.jwd") - Args.Add("Mode", "1") - Args.Add("Jwd", ReadFile) - Dim InputValue As New RedisValue(New ProcessArgs(1, Args).sProcessArgs) - - m_RedisManager.Subscriber.Publish(InputChn, InputValue) - - sRead = System.Console.ReadLine() - End While + ' Impostazione path radice per i dati + m_sDataRoot = System.AppDomain.CurrentDomain.BaseDirectory + IniFile.SetIniFile(m_sDataRoot & "\EgwMultiEngineManagerConsole.ini") + Dim sCamExePath As String = "" + GetMainPrivateProfileString(S_GENERAL, K_CAMEXEPATH, "", sCamExePath) + System.Console.WriteLine("CAMExePath = " & sCamExePath) + Dim sMainLuaPath As String = "" + GetMainPrivateProfileString(S_GENERAL, K_MAINPIPELUA, "", sMainLuaPath) + System.Console.WriteLine("MainPipeLua = " & sMainLuaPath) + Dim nMaxCamInstances As Integer = GetMainPrivateProfileInt(S_GENERAL, K_MAXCAMINSTANCES, nMaxCamInstances) + System.Console.WriteLine("MaxCAMInstances = " & nMaxCamInstances) + m_ExecProcessManager = New ExecProcessManager(sCamExePath, sMainLuaPath, nMaxCamInstances, ReturnModes.EVENT_) + m_ExecProcessManager.StartExecutionThread() + AddHandler m_ExecProcessManager.m_AnswerReceived, AddressOf ExecProcessManager_AnswerReceived + Dim sConnection As String = "localhost" + GetMainPrivateProfileString(S_GENERAL, K_REDISCONNECTION, "", sConnection) + System.Console.WriteLine("RedisConnection = " & sConnection) + If String.IsNullOrWhiteSpace(sConnection) Then + System.Console.WriteLine("Redis connection string is empty!") + Else + m_RedisManager = New RedisManager(sConnection) + m_RedisManager.SubscribeChannel(Chn_EgwEngineInput, AddressOf EgwEngineInputHandler) End If End Sub Private Sub ExecProcessManager_AnswerReceived(Answer As ProcessArgsResult) m_RedisManager.Subscriber.Publish(OutputChn, JsonConvert.SerializeObject(Answer)) m_stopWatch.Stop() - ' Get the elapsed time as a TimeSpan value. - Dim ts As TimeSpan = m_stopWatch.Elapsed - ' Format and display the TimeSpan value. - Dim elapsedTime As String = String.Format("{0:N3}", ts.TotalMilliseconds) - System.Console.WriteLine("Risposto in " + elapsedTime) + Dim elapsedTime As String = String.Format("{0:N3}", m_stopWatch.Elapsed.TotalMilliseconds) + System.Console.WriteLine("Send answer in " & elapsedTime & "ms") End Sub Private Sub EgwEngineInputHandler(RedisChannel As RedisChannel, RedisValue As RedisValue) - 'System.Console.WriteLine("Ricevuto valore " & RedisValue.ToString() & " dal canale " & RedisChannel.ToString()) - System.Console.WriteLine("Ricevuto valore dal canale " & RedisChannel.ToString()) + System.Console.WriteLine("Received value from channel " & RedisChannel.ToString()) m_stopWatch.Restart() Dim Request As ProcessArgs = JsonConvert.DeserializeObject(Of ProcessArgs)(RedisValue) m_ExecProcessManager.ArgumentsEnqueue(Request) End Sub - Private Sub EgwEngineOutputHandler(RedisChannel As RedisChannel, RedisValue As RedisValue) - System.Console.WriteLine("Ricevuto valore " & RedisValue.ToString() & " dal canale " & RedisChannel.ToString()) - End Sub - End Module diff --git a/EgwMultiEngineManager.Console/Utility/GenInterface.vb b/EgwMultiEngineManager.Console/Utility/GenInterface.vb new file mode 100644 index 0000000..f7bf24d --- /dev/null +++ b/EgwMultiEngineManager.Console/Utility/GenInterface.vb @@ -0,0 +1,76 @@ +Imports System.Globalization +Imports System.Runtime.InteropServices +Imports System.Text + +Public Module GenInterface + + '-------------------------------- IniFile : Get -------------------------------------------------- + + Public Function GetPrivateProfileInt( + lpAppName As String, + lpKeyName As String, + nDefault As Integer, + lpFileName As String) As Integer + End Function + + Public Function GetPrivateProfileDouble( + lpAppName As String, + lpKeyName As String, + dDefault As Double, + lpFileName As String) As Double + Dim sValue As String = String.Empty + GetPrivateProfileString(lpAppName, lpKeyName, dDefault.ToString(), sValue, lpFileName) + Dim nPos As Integer = sValue.IndexOf(";") + If nPos >= 0 Then + sValue = sValue.Remove(nPos) + End If + Dim dValue As Double + If Not Double.TryParse(sValue, NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, dValue) Then + dValue = dDefault + End If + Return dValue + End Function + + + Private Function GetPrivateProfileString( + lpAppName As String, + lpKeyName As String, + lpDefault As String, + lpReturnedString As StringBuilder, + nSize As Integer, + lpFileName As String) As Integer + End Function + Public Function GetPrivateProfileString( + lpAppName As String, + lpKeyName As String, + lpDefault As String, + ByRef lpString As String, + lpFileName As String) As Integer + Dim sb As New StringBuilder(1024) + Dim nRet As Integer = GetPrivateProfileString(lpAppName, lpKeyName, lpDefault, sb, sb.Capacity, lpFileName) + lpString = sb.ToString + Return nRet + End Function + + '-------------------------------- IniFile : Write ------------------------------------------------ + + Public Function WritePrivateProfileString( + lpAppName As String, + lpKeyName As String, + lpString As String, + lpFileName As String) As Boolean + End Function + + '-------------------------------- Windows -------------------------------------------------------- + Public Enum SW As Integer + HIDE = 0 + SHOWMAXIMIZED = 3 + RESTORE = 9 + End Enum + + + Public Function ShowWindow(hWnd As IntPtr, nCmdShow As Integer) As Boolean + End Function + + +End Module diff --git a/EgwMultiEngineManager.Console/Utility/IniFile.vb b/EgwMultiEngineManager.Console/Utility/IniFile.vb new file mode 100644 index 0000000..f2cd2ff --- /dev/null +++ b/EgwMultiEngineManager.Console/Utility/IniFile.vb @@ -0,0 +1,59 @@ +'---------------------------------------------------------------------------- +' EgalTech 2017-2017 +'---------------------------------------------------------------------------- +' File : IniFile.vb Data : 08.05.24 Versione : 2.6e1 +' Contenuto : Modulo IniFile per gestione lettura/scrittura da file INI. +' +' +' +' Modifiche : 08.05.24 ES Creazione modulo. +' +' +'---------------------------------------------------------------------------- + + +Imports System.Collections.ObjectModel + +Public Module IniFile + + Private m_sPath As String + Public ReadOnly Property sPath As String + Get + Return m_sPath + End Get + End Property + Public Sub SetIniFile(sPath) + m_sPath = sPath + End Sub + + Public Function GetMainPrivateProfileInt(IpAppName As String, IpKeyName As String, nDefault As Integer) As Integer + Return GetPrivateProfileInt(IpAppName, IpKeyName, nDefault, m_sPath) + End Function + + Public Function GetMainPrivateProfileDouble(IpAppName As String, IpKeyName As String, dDefault As Double) As Double + Return GetPrivateProfileDouble(IpAppName, IpKeyName, dDefault, m_sPath) + End Function + + Public Function GetMainPrivateProfileString(IpAppName As String, IpKeyName As String, IpDefault As String, ByRef IpString As String) As Integer + Return GetPrivateProfileString(IpAppName, IpKeyName, IpDefault, IpString, m_sPath) + End Function + + 'Public Function GetPrivateProfileLanguage(lpAppName As String, lpKeyName As String, lpFileName As String) As Language + ' Dim sVal As String = String.Empty + ' GetPrivateProfileString(lpAppName, lpKeyName, "", sVal, lpFileName) + ' Dim sItems() As String = sVal.Split(",".ToCharArray) + ' If sItems.Count() = 2 Then + ' Return New Language(sItems(0), sItems(1)) + ' End If + ' Return Nothing + 'End Function + + 'Public Function GetMainPrivateProfileLanguage(lpAppName As String, lpKeyName As String) As Language + ' Return GetPrivateProfileLanguage(lpAppName, lpKeyName, m_sPath) + 'End Function + + Public Function WriteMainPrivateProfileString(IpAppName As String, IpKeyName As String, ByRef IpString As String) As Boolean + Return WritePrivateProfileString(IpAppName, IpKeyName, IpString, m_sPath) + End Function + +End Module diff --git a/EgwMultiEngineManager.Console/Utility/RedisManager.vb b/EgwMultiEngineManager.Console/Utility/RedisManager.vb index 6964fa0..5328bc3 100644 --- a/EgwMultiEngineManager.Console/Utility/RedisManager.vb +++ b/EgwMultiEngineManager.Console/Utility/RedisManager.vb @@ -11,52 +11,30 @@ Class RedisManager End Get End Property - ' indice del Db Redis - Private m_nRedisDbIndex As Integer = 0 - Public ReadOnly Property nRedisDbIndex As Integer - Get - Return m_nRedisDbIndex - End Get - End Property - - ' Database Redis - Private m_RedisDb As IDatabase - Public ReadOnly Property RedisDb As IDatabase - Get - Return m_RedisDb - End Get - End Property - ' gestore sottoscrizioni Private m_Subscriber As ISubscriber Public ReadOnly Property Subscriber As ISubscriber Get + If m_Subscriber Is Nothing Then + ' inizializzo sottoscrizione + m_Subscriber = m_RedisConnection.GetSubscriber() + End If Return m_Subscriber End Get End Property - Sub New(sConnection As String, nDbIndex As Integer) + Sub New(sConnection As String) Try ' inizializzo connessione al server Redis m_RedisConnection = ConnectionMultiplexer.Connect(sConnection) - m_RedisDb = m_RedisConnection.GetDatabase(nDbIndex) - ' inizializzo sottoscrizioni - m_Subscriber = m_RedisConnection.GetSubscriber() - 'Dim InputChn As New RedisChannel("Messages", RedisChannel.PatternMode.Auto) - 'm_Subscriber.Subscribe(InputChn, AddressOf SubscribeHandler) Catch ex As Exception System.Console.WriteLine("Redis connection error!! " & Environment.NewLine & ex.Message) End Try End Sub - Private Sub SubscribeHandler(RedisChannel As RedisChannel, RedisValue As RedisValue) - System.Console.WriteLine("Ricevuto valore " & RedisValue.ToString() & " dal canale " & RedisChannel.ToString()) - End Sub - Friend Sub SubscribeChannel(sName As String, Handler As Action(Of RedisChannel, RedisValue)) - m_Subscriber = m_RedisConnection.GetSubscriber() Dim InputChn As New RedisChannel(sName, RedisChannel.PatternMode.Auto) - m_Subscriber.Subscribe(InputChn, Handler) + Subscriber.Subscribe(InputChn, Handler) End Sub End Class diff --git a/EgwMultiEngineManager.Service/App.config b/EgwMultiEngineManager.Service/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/EgwMultiEngineManager.Service/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/EgwMultiEngineManager.Service/Constants/ConstIni.vb b/EgwMultiEngineManager.Service/Constants/ConstIni.vb new file mode 100644 index 0000000..9d44097 --- /dev/null +++ b/EgwMultiEngineManager.Service/Constants/ConstIni.vb @@ -0,0 +1,23 @@ +'---------------------------------------------------------------------------- +' EgalTech 2015-2024 +'---------------------------------------------------------------------------- +' File : ConstIni.vb Data : 08.05.24 Versione : 2.6e1 +' Contenuto : Modulo costanti sezione e chiavi per file Ini. +' +' +' +' Modifiche : 08.05.24 ES Creazione modulo. +' +' +'---------------------------------------------------------------------------- +Module ConstIni + + Public Const INI_FILE_NAME As String = "Effector.Plugin.FiveLakes.ini" + + Public Const S_GENERAL As String = "General" + Public Const K_CAMEXEPATH As String = "CAMExePath" + Public Const K_MAINPIPELUA As String = "MainPipeLua" + Public Const K_REDISCONNECTION As String = "RedisConnection" + Public Const K_MAXCAMINSTANCES As String = "MaxCAMInstances" + +End Module diff --git a/EgwMultiEngineManager.Service/EgwMultiEngineManager.Service.vbproj b/EgwMultiEngineManager.Service/EgwMultiEngineManager.Service.vbproj new file mode 100644 index 0000000..dff684d --- /dev/null +++ b/EgwMultiEngineManager.Service/EgwMultiEngineManager.Service.vbproj @@ -0,0 +1,191 @@ + + + + + Debug + AnyCPU + {8E7E3A34-B34C-4F21-AFB7-8CF1FD702EB9} + WinExe + EgwMultiEngineManager.Service.MainService + EgwMultiEngineManager.Service + EgwMultiEngineManager.Service + 512 + Console + v4.7.2 + true + true + + + + + AnyCPU + true + full + true + true + bin\Debug\ + EgwMultiEngineManager.Service.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + AnyCPU + pdbonly + false + true + true + bin\Release\ + EgwMultiEngineManager.Service.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + On + + + Binary + + + Off + + + On + + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\packages\Microsoft.Extensions.Logging.Abstractions.6.0.0\lib\net461\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Pipelines.Sockets.Unofficial.2.2.8\lib\net472\Pipelines.Sockets.Unofficial.dll + + + ..\packages\StackExchange.Redis.2.8.58\lib\net472\StackExchange.Redis.dll + + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + + + + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + True + True + + + ..\packages\System.IO.Pipelines.5.0.1\lib\net461\System.IO.Pipelines.dll + + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + + ..\packages\System.Threading.Channels.5.0.0\lib\net461\System.Threading.Channels.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + + + + + + + + + + + + + + True + Application.myapp + + + Component + + + MainService.vb + + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ProjectInstaller.vb + + + Component + + + + + + + + MainService.vb + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + Designer + + + ProjectInstaller.vb + + + + + MyApplicationCodeGenerator + Application.Designer.vb + + + SettingsSingleFileGenerator + My + Settings.Designer.vb + + + + + + + {6359139b-a3ad-4502-90f3-2d422119273d} + EgwMultiEngineManager + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/EgwMultiEngineManager.Service/MainService.Designer.vb b/EgwMultiEngineManager.Service/MainService.Designer.vb new file mode 100644 index 0000000..0fa3f04 --- /dev/null +++ b/EgwMultiEngineManager.Service/MainService.Designer.vb @@ -0,0 +1,51 @@ +Imports System.ServiceProcess + + _ +Partial Class MainService + Inherits System.ServiceProcess.ServiceBase + + 'UserService overrides dispose to clean up the component list. + _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + ' The main entry point for the process + _ + _ + 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 MainService} + + System.ServiceProcess.ServiceBase.Run(ServicesToRun) + End Sub + + 'Required by the Component Designer + Private components As System.ComponentModel.IContainer + + ' NOTE: The following procedure is required by the Component Designer + ' It can be modified using the Component Designer. + ' Do not modify it using the code editor. + _ + Private Sub InitializeComponent() + ' + 'MainService + ' + Me.ServiceName = "EgwMultiEngineManagerService" + + End Sub + +End Class diff --git a/EgwMultiEngineManager.Service/MainService.resx b/EgwMultiEngineManager.Service/MainService.resx new file mode 100644 index 0000000..e5858cc --- /dev/null +++ b/EgwMultiEngineManager.Service/MainService.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/EgwMultiEngineManager.Service/MainService.vb b/EgwMultiEngineManager.Service/MainService.vb new file mode 100644 index 0000000..9d1c0bd --- /dev/null +++ b/EgwMultiEngineManager.Service/MainService.vb @@ -0,0 +1,80 @@ +Imports EgwMultiEngineManager.ExecProcessManager +Imports Newtonsoft.Json +Imports StackExchange.Redis + +Public Class MainService + + Private Const Chn_EgwEngineInput As String = "EgwEngineInput" + Private Const Chn_EgwEngineOutput As String = "EgwEngineOutput" + + Private m_sDataRoot As String = String.Empty + Friend ReadOnly Property sDataRoot As String + Get + Return m_sDataRoot + End Get + End Property + + Private m_ExecProcessManager As ExecProcessManager + + Private m_stopWatch As New Stopwatch() + + ' Riferimento al gestore del server Redis + Private m_RedisManager As RedisManager + Friend ReadOnly Property RedisManager As RedisManager + Get + Return m_RedisManager + End Get + End Property + + Private OutputChn As New RedisChannel(Chn_EgwEngineOutput, RedisChannel.PatternMode.Auto) + + Protected Overrides Sub OnStart(ByVal args() As String) + ' Add code here to start your service. This method should set things + ' in motion so your service can do its work. + ' Impostazione path radice per i dati + m_sDataRoot = System.AppDomain.CurrentDomain.BaseDirectory + IniFile.SetIniFile(m_sDataRoot & "\EgwMultiEngineManagerConsole.ini") + Dim sCamExePath As String = "" + GetMainPrivateProfileString(S_GENERAL, K_CAMEXEPATH, "", sCamExePath) + System.Console.WriteLine("CAMExePath = " & sCamExePath) + Dim sMainLuaPath As String = "" + GetMainPrivateProfileString(S_GENERAL, K_MAINPIPELUA, "", sMainLuaPath) + System.Console.WriteLine("MainPipeLua = " & sMainLuaPath) + Dim nMaxCamInstances As Integer = GetMainPrivateProfileInt(S_GENERAL, K_MAXCAMINSTANCES, nMaxCamInstances) + System.Console.WriteLine("MaxCAMInstances = " & nMaxCamInstances) + m_ExecProcessManager = New ExecProcessManager(sCamExePath, sMainLuaPath, nMaxCamInstances, ReturnModes.EVENT_) + m_ExecProcessManager.StartExecutionThread() + AddHandler m_ExecProcessManager.m_AnswerReceived, AddressOf ExecProcessManager_AnswerReceived + Dim sConnection As String = "localhost" + GetMainPrivateProfileString(S_GENERAL, K_REDISCONNECTION, "", sConnection) + System.Console.WriteLine("RedisConnection = " & sConnection) + If String.IsNullOrWhiteSpace(sConnection) Then + System.Console.WriteLine("Redis connection string is empty!") + Else + m_RedisManager = New RedisManager(sConnection) + m_RedisManager.SubscribeChannel(Chn_EgwEngineInput, AddressOf EgwEngineInputHandler) + End If + End Sub + + Private Sub ExecProcessManager_AnswerReceived(Answer As ProcessArgsResult) + m_RedisManager.Subscriber.Publish(OutputChn, JsonConvert.SerializeObject(Answer)) + m_stopWatch.Stop() + ' Format and display the TimeSpan value. + Dim elapsedTime As String = String.Format("{0:N3}", m_stopWatch.Elapsed.TotalMilliseconds) + System.Console.WriteLine("Send answer in " & elapsedTime & "ms") + End Sub + + Private Sub EgwEngineInputHandler(RedisChannel As RedisChannel, RedisValue As RedisValue) + System.Console.WriteLine("Received value from channel " & RedisChannel.ToString()) + m_stopWatch.Restart() + Dim Request As ProcessArgs = JsonConvert.DeserializeObject(Of ProcessArgs)(RedisValue) + m_ExecProcessManager.ArgumentsEnqueue(Request) + End Sub + + + Protected Overrides Sub OnStop() + ' Add code here to perform any tear-down necessary to stop your service. + m_ExecProcessManager.StopExecutionThread() + End Sub + +End Class diff --git a/EgwMultiEngineManager.Service/My Project/Application.Designer.vb b/EgwMultiEngineManager.Service/My Project/Application.Designer.vb new file mode 100644 index 0000000..88dd01c --- /dev/null +++ b/EgwMultiEngineManager.Service/My Project/Application.Designer.vb @@ -0,0 +1,13 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.42000 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + diff --git a/EgwMultiEngineManager.Service/My Project/Application.myapp b/EgwMultiEngineManager.Service/My Project/Application.myapp new file mode 100644 index 0000000..602de37 --- /dev/null +++ b/EgwMultiEngineManager.Service/My Project/Application.myapp @@ -0,0 +1,10 @@ + + + false + false + 0 + true + 0 + 3 + true + diff --git a/EgwMultiEngineManager.Service/My Project/AssemblyInfo.vb b/EgwMultiEngineManager.Service/My Project/AssemblyInfo.vb new file mode 100644 index 0000000..ff1c54a --- /dev/null +++ b/EgwMultiEngineManager.Service/My Project/AssemblyInfo.vb @@ -0,0 +1,32 @@ +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' General Information about an assembly is controlled through the following +' set of attributes. Change these attribute values to modify the information +' associated with an assembly. + +' Review the values of the assembly attributes + + + + + + + + + + +'The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' + + + diff --git a/EgwMultiEngineManager.Service/My Project/Resources.Designer.vb b/EgwMultiEngineManager.Service/My Project/Resources.Designer.vb new file mode 100644 index 0000000..282a612 --- /dev/null +++ b/EgwMultiEngineManager.Service/My Project/Resources.Designer.vb @@ -0,0 +1,62 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.42000 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + + +Namespace My.Resources + + 'This class was auto-generated by the StronglyTypedResourceBuilder + 'class via a tool like ResGen or Visual Studio. + 'To add or remove a member, edit your .ResX file then rerun ResGen + 'with the /str option, or rebuild your VS project. + ''' + ''' A strongly-typed resource class, for looking up localized strings, etc. + ''' + _ + Friend Module Resources + + Private resourceMan As Global.System.Resources.ResourceManager + + Private resourceCulture As Global.System.Globalization.CultureInfo + + ''' + ''' Returns the cached ResourceManager instance used by this class. + ''' + _ + Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager + Get + If Object.ReferenceEquals(resourceMan, Nothing) Then + Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("EgwMultiEngineManager.Service.Resources", GetType(Resources).Assembly) + resourceMan = temp + End If + Return resourceMan + End Get + End Property + + ''' + ''' Overrides the current thread's CurrentUICulture property for all + ''' resource lookups using this strongly typed resource class. + ''' + _ + Friend Property Culture() As Global.System.Globalization.CultureInfo + Get + Return resourceCulture + End Get + Set(ByVal value As Global.System.Globalization.CultureInfo) + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/EgwMultiEngineManager.Service/My Project/Resources.resx b/EgwMultiEngineManager.Service/My Project/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/EgwMultiEngineManager.Service/My Project/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/EgwMultiEngineManager.Service/My Project/Settings.Designer.vb b/EgwMultiEngineManager.Service/My Project/Settings.Designer.vb new file mode 100644 index 0000000..fad844c --- /dev/null +++ b/EgwMultiEngineManager.Service/My Project/Settings.Designer.vb @@ -0,0 +1,73 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.42000 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) + +#Region "My.Settings Auto-Save Functionality" +#If _MyType = "WindowsForms" Then + Private Shared addedHandler As Boolean + + Private Shared addedHandlerLockObject As New Object + + _ + Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) + If My.Application.SaveMySettingsOnExit Then + My.Settings.Save() + End If + End Sub +#End If +#End Region + + Public Shared ReadOnly Property [Default]() As MySettings + Get + +#If _MyType = "WindowsForms" Then + If Not addedHandler Then + SyncLock addedHandlerLockObject + If Not addedHandler Then + AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings + addedHandler = True + End If + End SyncLock + End If +#End If + Return defaultInstance + End Get + End Property + End Class +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.EgwMultiEngineManager.Service.My.MySettings + Get + Return Global.EgwMultiEngineManager.Service.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/EgwMultiEngineManager.Service/My Project/Settings.settings b/EgwMultiEngineManager.Service/My Project/Settings.settings new file mode 100644 index 0000000..85b890b --- /dev/null +++ b/EgwMultiEngineManager.Service/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/EgwMultiEngineManager.Service/ProjectInstaller.Designer.vb b/EgwMultiEngineManager.Service/ProjectInstaller.Designer.vb new file mode 100644 index 0000000..003ae35 --- /dev/null +++ b/EgwMultiEngineManager.Service/ProjectInstaller.Designer.vb @@ -0,0 +1,48 @@ + Partial Class ProjectInstaller + Inherits System.Configuration.Install.Installer + + 'Installer overrides dispose to clean up the component list. + _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Component Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Component Designer + 'It can be modified using the Component Designer. + 'Do not modify it using the code editor. + _ + Private Sub InitializeComponent() + Me.ServiceProcessInstaller1 = New System.ServiceProcess.ServiceProcessInstaller() + Me.ServiceInstaller1 = New System.ServiceProcess.ServiceInstaller() + ' + 'ServiceProcessInstaller1 + ' + Me.ServiceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem + Me.ServiceProcessInstaller1.Password = Nothing + Me.ServiceProcessInstaller1.Username = Nothing + ' + 'ServiceInstaller1 + ' + Me.ServiceInstaller1.Description = "Manage the running EgtEngines" + Me.ServiceInstaller1.DisplayName = "EgwMultiEngineManagerService" + Me.ServiceInstaller1.ServiceName = "EgwMultiEngineManagerService" + Me.ServiceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic + ' + 'ProjectInstaller + ' + Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceProcessInstaller1, Me.ServiceInstaller1}) + + End Sub + + Friend WithEvents ServiceProcessInstaller1 As ServiceProcess.ServiceProcessInstaller + Friend WithEvents ServiceInstaller1 As ServiceProcess.ServiceInstaller +End Class diff --git a/EgwMultiEngineManager.Service/ProjectInstaller.resx b/EgwMultiEngineManager.Service/ProjectInstaller.resx new file mode 100644 index 0000000..bd9eb69 --- /dev/null +++ b/EgwMultiEngineManager.Service/ProjectInstaller.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 262, 17 + + + False + + \ No newline at end of file diff --git a/EgwMultiEngineManager.Service/ProjectInstaller.vb b/EgwMultiEngineManager.Service/ProjectInstaller.vb new file mode 100644 index 0000000..b64862b --- /dev/null +++ b/EgwMultiEngineManager.Service/ProjectInstaller.vb @@ -0,0 +1,16 @@ +Imports System.ComponentModel +Imports System.Configuration.Install + +Public Class ProjectInstaller + + Public Sub New() + MyBase.New() + + 'This call is required by the Component Designer. + InitializeComponent() + + 'Add initialization code after the call to InitializeComponent + + End Sub + +End Class diff --git a/EgwMultiEngineManager.Service/Utility/GenInterface.vb b/EgwMultiEngineManager.Service/Utility/GenInterface.vb new file mode 100644 index 0000000..f7bf24d --- /dev/null +++ b/EgwMultiEngineManager.Service/Utility/GenInterface.vb @@ -0,0 +1,76 @@ +Imports System.Globalization +Imports System.Runtime.InteropServices +Imports System.Text + +Public Module GenInterface + + '-------------------------------- IniFile : Get -------------------------------------------------- + + Public Function GetPrivateProfileInt( + lpAppName As String, + lpKeyName As String, + nDefault As Integer, + lpFileName As String) As Integer + End Function + + Public Function GetPrivateProfileDouble( + lpAppName As String, + lpKeyName As String, + dDefault As Double, + lpFileName As String) As Double + Dim sValue As String = String.Empty + GetPrivateProfileString(lpAppName, lpKeyName, dDefault.ToString(), sValue, lpFileName) + Dim nPos As Integer = sValue.IndexOf(";") + If nPos >= 0 Then + sValue = sValue.Remove(nPos) + End If + Dim dValue As Double + If Not Double.TryParse(sValue, NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, dValue) Then + dValue = dDefault + End If + Return dValue + End Function + + + Private Function GetPrivateProfileString( + lpAppName As String, + lpKeyName As String, + lpDefault As String, + lpReturnedString As StringBuilder, + nSize As Integer, + lpFileName As String) As Integer + End Function + Public Function GetPrivateProfileString( + lpAppName As String, + lpKeyName As String, + lpDefault As String, + ByRef lpString As String, + lpFileName As String) As Integer + Dim sb As New StringBuilder(1024) + Dim nRet As Integer = GetPrivateProfileString(lpAppName, lpKeyName, lpDefault, sb, sb.Capacity, lpFileName) + lpString = sb.ToString + Return nRet + End Function + + '-------------------------------- IniFile : Write ------------------------------------------------ + + Public Function WritePrivateProfileString( + lpAppName As String, + lpKeyName As String, + lpString As String, + lpFileName As String) As Boolean + End Function + + '-------------------------------- Windows -------------------------------------------------------- + Public Enum SW As Integer + HIDE = 0 + SHOWMAXIMIZED = 3 + RESTORE = 9 + End Enum + + + Public Function ShowWindow(hWnd As IntPtr, nCmdShow As Integer) As Boolean + End Function + + +End Module diff --git a/EgwMultiEngineManager.Service/Utility/IniFile.vb b/EgwMultiEngineManager.Service/Utility/IniFile.vb new file mode 100644 index 0000000..f2cd2ff --- /dev/null +++ b/EgwMultiEngineManager.Service/Utility/IniFile.vb @@ -0,0 +1,59 @@ +'---------------------------------------------------------------------------- +' EgalTech 2017-2017 +'---------------------------------------------------------------------------- +' File : IniFile.vb Data : 08.05.24 Versione : 2.6e1 +' Contenuto : Modulo IniFile per gestione lettura/scrittura da file INI. +' +' +' +' Modifiche : 08.05.24 ES Creazione modulo. +' +' +'---------------------------------------------------------------------------- + + +Imports System.Collections.ObjectModel + +Public Module IniFile + + Private m_sPath As String + Public ReadOnly Property sPath As String + Get + Return m_sPath + End Get + End Property + Public Sub SetIniFile(sPath) + m_sPath = sPath + End Sub + + Public Function GetMainPrivateProfileInt(IpAppName As String, IpKeyName As String, nDefault As Integer) As Integer + Return GetPrivateProfileInt(IpAppName, IpKeyName, nDefault, m_sPath) + End Function + + Public Function GetMainPrivateProfileDouble(IpAppName As String, IpKeyName As String, dDefault As Double) As Double + Return GetPrivateProfileDouble(IpAppName, IpKeyName, dDefault, m_sPath) + End Function + + Public Function GetMainPrivateProfileString(IpAppName As String, IpKeyName As String, IpDefault As String, ByRef IpString As String) As Integer + Return GetPrivateProfileString(IpAppName, IpKeyName, IpDefault, IpString, m_sPath) + End Function + + 'Public Function GetPrivateProfileLanguage(lpAppName As String, lpKeyName As String, lpFileName As String) As Language + ' Dim sVal As String = String.Empty + ' GetPrivateProfileString(lpAppName, lpKeyName, "", sVal, lpFileName) + ' Dim sItems() As String = sVal.Split(",".ToCharArray) + ' If sItems.Count() = 2 Then + ' Return New Language(sItems(0), sItems(1)) + ' End If + ' Return Nothing + 'End Function + + 'Public Function GetMainPrivateProfileLanguage(lpAppName As String, lpKeyName As String) As Language + ' Return GetPrivateProfileLanguage(lpAppName, lpKeyName, m_sPath) + 'End Function + + Public Function WriteMainPrivateProfileString(IpAppName As String, IpKeyName As String, ByRef IpString As String) As Boolean + Return WritePrivateProfileString(IpAppName, IpKeyName, IpString, m_sPath) + End Function + +End Module diff --git a/EgwMultiEngineManager.Service/Utility/RedisManager.vb b/EgwMultiEngineManager.Service/Utility/RedisManager.vb new file mode 100644 index 0000000..5328bc3 --- /dev/null +++ b/EgwMultiEngineManager.Service/Utility/RedisManager.vb @@ -0,0 +1,40 @@ +Imports System +Imports StackExchange.Redis + +Class RedisManager + + ' connessione al server Redis + Private m_RedisConnection As ConnectionMultiplexer + Public ReadOnly Property RedisConnection As ConnectionMultiplexer + Get + Return m_RedisConnection + End Get + End Property + + ' gestore sottoscrizioni + Private m_Subscriber As ISubscriber + Public ReadOnly Property Subscriber As ISubscriber + Get + If m_Subscriber Is Nothing Then + ' inizializzo sottoscrizione + m_Subscriber = m_RedisConnection.GetSubscriber() + End If + Return m_Subscriber + End Get + End Property + + Sub New(sConnection As String) + Try + ' inizializzo connessione al server Redis + m_RedisConnection = ConnectionMultiplexer.Connect(sConnection) + Catch ex As Exception + System.Console.WriteLine("Redis connection error!! " & Environment.NewLine & ex.Message) + End Try + End Sub + + Friend Sub SubscribeChannel(sName As String, Handler As Action(Of RedisChannel, RedisValue)) + Dim InputChn As New RedisChannel(sName, RedisChannel.PatternMode.Auto) + Subscriber.Subscribe(InputChn, Handler) + End Sub + +End Class diff --git a/EgwMultiEngineManager.Service/packages.config b/EgwMultiEngineManager.Service/packages.config new file mode 100644 index 0000000..3934910 --- /dev/null +++ b/EgwMultiEngineManager.Service/packages.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/EgwMultiEngineManager.sln b/EgwMultiEngineManager.sln index e1d6282..5982cba 100644 --- a/EgwMultiEngineManager.sln +++ b/EgwMultiEngineManager.sln @@ -9,6 +9,8 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "EgwMultiEngineManager.Test" EndProject Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "EgwMultiEngineManager.Console", "EgwMultiEngineManager.Console\EgwMultiEngineManager.Console.vbproj", "{95E6D3B9-1E04-4A63-86ED-4F1F6593B71C}" EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "EgwMultiEngineManager.Service", "EgwMultiEngineManager.Service\EgwMultiEngineManager.Service.vbproj", "{8E7E3A34-B34C-4F21-AFB7-8CF1FD702EB9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +29,10 @@ Global {95E6D3B9-1E04-4A63-86ED-4F1F6593B71C}.Debug|Any CPU.Build.0 = Debug|Any CPU {95E6D3B9-1E04-4A63-86ED-4F1F6593B71C}.Release|Any CPU.ActiveCfg = Release|Any CPU {95E6D3B9-1E04-4A63-86ED-4F1F6593B71C}.Release|Any CPU.Build.0 = Release|Any CPU + {8E7E3A34-B34C-4F21-AFB7-8CF1FD702EB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E7E3A34-B34C-4F21-AFB7-8CF1FD702EB9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E7E3A34-B34C-4F21-AFB7-8CF1FD702EB9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E7E3A34-B34C-4F21-AFB7-8CF1FD702EB9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE