From 6b955569f62919bce355609f28c1a6a53a4605eb Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Thu, 12 Sep 2019 17:06:14 +0200 Subject: [PATCH] monster commit for zoo flow, prepare migration of cw --- DDLicenseService/DDEDMLicenseService.vbproj | 2 +- DDLicenseService/packages.config | 2 +- DDMonorepo.sln | 14 + DDTestService/DDTestService.vbproj | 2 +- DDTestService/packages.config | 2 +- DDZUGFeRDService/DDZUGFeRDService.vbproj | 2 +- DDZUGFeRDService/packages.config | 2 +- EDMI_FILE_OPs/EDMIAPI.vbproj | 2 +- EDMI_FILE_OPs/packages.config | 2 +- Filesystem/Filesystem.vbproj | 2 +- Filesystem/packages.config | 2 +- GUIs.ClientSuite/ClientSuite.vbproj | 2 +- GUIs.ClientSuite/packages.config | 2 +- Jobs/Jobs.vbproj | 2 +- Jobs/packages.config | 2 +- Message/Messaging.vbproj | 2 +- Message/packages.config | 2 +- Modules.Config/Config.vbproj | 2 +- Modules.Config/packages.config | 2 +- Modules.Database/Database.vbproj | 2 +- Modules.Database/packages.config | 2 +- Modules.Interfaces/Interfaces.vbproj | 2 +- Modules.Interfaces/packages.config | 2 +- Modules.License/License.vbproj | 2 +- Modules.License/packages.config | 2 +- Modules.Logging/Logging.vbproj | 2 +- Modules.Logging/packages.config | 2 +- Modules.Windream/Windream.vbproj | 2 +- Modules.Windream/packages.config | 2 +- Modules/ZooFlow/ClassProfileFilter.vb | 483 +++++++++++++++++ Modules/ZooFlow/Environment.vb | 4 + .../My Project/Application.Designer.vb | 13 + Modules/ZooFlow/My Project/Application.myapp | 10 + Modules/ZooFlow/My Project/AssemblyInfo.vb | 35 ++ .../ZooFlow/My Project/Resources.Designer.vb | 63 +++ Modules/ZooFlow/My Project/Resources.resx | 117 +++++ .../ZooFlow/My Project/Settings.Designer.vb | 73 +++ Modules/ZooFlow/My Project/Settings.settings | 7 + .../ZooFlow/Params/ClipboardWatcherParams.vb | 5 + Modules/ZooFlow/Params/ProfileData.vb | 47 ++ Modules/ZooFlow/State/ModuleState.vb | 7 + Modules/ZooFlow/State/ServiceState.vb | 6 + Modules/ZooFlow/State/UserState.vb | 28 + Modules/ZooFlow/ZooFlow.vbproj | 135 +++++ Modules/ZooFlow/packages.config | 4 + .../ClipboardWatcher.vbproj | 30 +- .../My Project/licenses.licx | 1 + .../frmMatch.Designer.vb | 62 +++ Products.ClipboardWatcher/frmMatch.vb | 133 ++++- Products.ClipboardWatcher/packages.config | 4 + .../DDEDM_NetworkService/IDBService.vbproj | 2 +- SERVICES/DDEDM_NetworkService/packages.config | 2 +- Service.JobRunner/JobRunner.vbproj | 2 +- Service.JobRunner/packages.config | 2 +- Windows/My Project/Application.Designer.vb | 13 + Windows/My Project/Application.myapp | 10 + Windows/My Project/AssemblyInfo.vb | 35 ++ Windows/My Project/Resources.Designer.vb | 63 +++ Windows/My Project/Resources.resx | 117 +++++ Windows/My Project/Settings.Designer.vb | 73 +++ Windows/My Project/Settings.settings | 7 + Windows/NativeMethods.vb | 102 ++++ Windows/Utils.vb | 96 ++++ Windows/Window.vb | 121 +++++ Windows/Windows.vbproj | 121 +++++ Windows/packages.config | 4 + ZooFlow/ApplicationEvents.vb | 1 + ZooFlow/ClassInit.vb | 22 +- ZooFlow/ClassProfileFilter.vb | 495 ++++++++++++++++++ ZooFlow/ClipboardWatcher/State.vb | 8 + ZooFlow/Common/ClassCommon.vb | 3 - .../ZooFlow.State.ClassUserState.datasource | 10 + ZooFlow/My Project/licenses.licx | 11 +- ZooFlow/MyApplication.vb | 18 +- .../Queries/ClassClipboardWatcherQueries.vb | 17 + .../{Common => Queries}/ClassCommonQueries.vb | 0 ZooFlow/Queries/ClassQueries.vb | 4 + ZooFlow/State/ClassModuleState.vb | 5 - ZooFlow/State/ClassServiceState.vb | 4 - ZooFlow/State/ClassUserState.vb | 25 - ZooFlow/ZooFlow.vbproj | 28 +- ZooFlow/frmMain.Designer.vb | 30 +- ZooFlow/frmMain.resx | 66 ++- ZooFlow/frmMain.vb | 104 +++- ZooFlow/frmSettings.Designer.vb | 147 ++++++ ZooFlow/frmSettings.resx | 18 + ZooFlow/frmSettings.vb | 4 +- ZooFlow/packages.config | 2 +- 88 files changed, 3000 insertions(+), 129 deletions(-) create mode 100644 Modules/ZooFlow/ClassProfileFilter.vb create mode 100644 Modules/ZooFlow/Environment.vb create mode 100644 Modules/ZooFlow/My Project/Application.Designer.vb create mode 100644 Modules/ZooFlow/My Project/Application.myapp create mode 100644 Modules/ZooFlow/My Project/AssemblyInfo.vb create mode 100644 Modules/ZooFlow/My Project/Resources.Designer.vb create mode 100644 Modules/ZooFlow/My Project/Resources.resx create mode 100644 Modules/ZooFlow/My Project/Settings.Designer.vb create mode 100644 Modules/ZooFlow/My Project/Settings.settings create mode 100644 Modules/ZooFlow/Params/ClipboardWatcherParams.vb create mode 100644 Modules/ZooFlow/Params/ProfileData.vb create mode 100644 Modules/ZooFlow/State/ModuleState.vb create mode 100644 Modules/ZooFlow/State/ServiceState.vb create mode 100644 Modules/ZooFlow/State/UserState.vb create mode 100644 Modules/ZooFlow/ZooFlow.vbproj create mode 100644 Modules/ZooFlow/packages.config create mode 100644 Products.ClipboardWatcher/My Project/licenses.licx create mode 100644 Products.ClipboardWatcher/packages.config create mode 100644 Windows/My Project/Application.Designer.vb create mode 100644 Windows/My Project/Application.myapp create mode 100644 Windows/My Project/AssemblyInfo.vb create mode 100644 Windows/My Project/Resources.Designer.vb create mode 100644 Windows/My Project/Resources.resx create mode 100644 Windows/My Project/Settings.Designer.vb create mode 100644 Windows/My Project/Settings.settings create mode 100644 Windows/NativeMethods.vb create mode 100644 Windows/Utils.vb create mode 100644 Windows/Window.vb create mode 100644 Windows/Windows.vbproj create mode 100644 Windows/packages.config create mode 100644 ZooFlow/ClassProfileFilter.vb create mode 100644 ZooFlow/ClipboardWatcher/State.vb delete mode 100644 ZooFlow/Common/ClassCommon.vb create mode 100644 ZooFlow/My Project/DataSources/ZooFlow.State.ClassUserState.datasource create mode 100644 ZooFlow/Queries/ClassClipboardWatcherQueries.vb rename ZooFlow/{Common => Queries}/ClassCommonQueries.vb (100%) create mode 100644 ZooFlow/Queries/ClassQueries.vb delete mode 100644 ZooFlow/State/ClassModuleState.vb delete mode 100644 ZooFlow/State/ClassServiceState.vb delete mode 100644 ZooFlow/State/ClassUserState.vb diff --git a/DDLicenseService/DDEDMLicenseService.vbproj b/DDLicenseService/DDEDMLicenseService.vbproj index 6be2d11c..c16041b0 100644 --- a/DDLicenseService/DDEDMLicenseService.vbproj +++ b/DDLicenseService/DDEDMLicenseService.vbproj @@ -49,7 +49,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/DDLicenseService/packages.config b/DDLicenseService/packages.config index f89fa324..99e34262 100644 --- a/DDLicenseService/packages.config +++ b/DDLicenseService/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/DDMonorepo.sln b/DDMonorepo.sln index 9dc6106e..b98fc8fa 100644 --- a/DDMonorepo.sln +++ b/DDMonorepo.sln @@ -86,6 +86,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Products", "Products", "{EB EndProject Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ClipboardWatcher", "Products.ClipboardWatcher\ClipboardWatcher.vbproj", "{1FBA063D-60A5-4FC8-A529-A3D1ECFD640C}" EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Windows", "Windows\Windows.vbproj", "{5EFAEF9B-90B9-4F05-9F70-F79AD77FFF86}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ZooFlow", "Modules\ZooFlow\ZooFlow.vbproj", "{81CAC44F-3711-4C8F-AE98-E02A7448782A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -212,6 +216,14 @@ Global {1FBA063D-60A5-4FC8-A529-A3D1ECFD640C}.Debug|Any CPU.Build.0 = Debug|Any CPU {1FBA063D-60A5-4FC8-A529-A3D1ECFD640C}.Release|Any CPU.ActiveCfg = Release|Any CPU {1FBA063D-60A5-4FC8-A529-A3D1ECFD640C}.Release|Any CPU.Build.0 = Release|Any CPU + {5EFAEF9B-90B9-4F05-9F70-F79AD77FFF86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5EFAEF9B-90B9-4F05-9F70-F79AD77FFF86}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5EFAEF9B-90B9-4F05-9F70-F79AD77FFF86}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5EFAEF9B-90B9-4F05-9F70-F79AD77FFF86}.Release|Any CPU.Build.0 = Release|Any CPU + {81CAC44F-3711-4C8F-AE98-E02A7448782A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81CAC44F-3711-4C8F-AE98-E02A7448782A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81CAC44F-3711-4C8F-AE98-E02A7448782A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81CAC44F-3711-4C8F-AE98-E02A7448782A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -247,6 +259,8 @@ Global {BCC6942F-CD4B-4B67-8200-1C0D002E7CC2} = {F98C0329-C004-417F-B2AB-7466E88D8220} {D0FB36EB-783D-40E1-B71E-A0B84B2FE567} = {8FFE925E-8B84-45F1-93CB-32B1C96F41EB} {1FBA063D-60A5-4FC8-A529-A3D1ECFD640C} = {EB026AEE-C702-47C6-82F5-956D5C8E26C2} + {5EFAEF9B-90B9-4F05-9F70-F79AD77FFF86} = {3E2008C8-27B1-41DD-9B1A-0C4029F6AECC} + {81CAC44F-3711-4C8F-AE98-E02A7448782A} = {3E2008C8-27B1-41DD-9B1A-0C4029F6AECC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C1BE4090-A0FD-48AF-86CB-39099D14B286} diff --git a/DDTestService/DDTestService.vbproj b/DDTestService/DDTestService.vbproj index 31cceea4..a0c8dbf5 100644 --- a/DDTestService/DDTestService.vbproj +++ b/DDTestService/DDTestService.vbproj @@ -52,7 +52,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/DDTestService/packages.config b/DDTestService/packages.config index f89fa324..99e34262 100644 --- a/DDTestService/packages.config +++ b/DDTestService/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/DDZUGFeRDService/DDZUGFeRDService.vbproj b/DDZUGFeRDService/DDZUGFeRDService.vbproj index 6c7b8cb1..7f98a253 100644 --- a/DDZUGFeRDService/DDZUGFeRDService.vbproj +++ b/DDZUGFeRDService/DDZUGFeRDService.vbproj @@ -49,7 +49,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/DDZUGFeRDService/packages.config b/DDZUGFeRDService/packages.config index f89fa324..99e34262 100644 --- a/DDZUGFeRDService/packages.config +++ b/DDZUGFeRDService/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/EDMI_FILE_OPs/EDMIAPI.vbproj b/EDMI_FILE_OPs/EDMIAPI.vbproj index 79a8574c..6454ba73 100644 --- a/EDMI_FILE_OPs/EDMIAPI.vbproj +++ b/EDMI_FILE_OPs/EDMIAPI.vbproj @@ -45,7 +45,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/EDMI_FILE_OPs/packages.config b/EDMI_FILE_OPs/packages.config index f89fa324..99e34262 100644 --- a/EDMI_FILE_OPs/packages.config +++ b/EDMI_FILE_OPs/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Filesystem/Filesystem.vbproj b/Filesystem/Filesystem.vbproj index 94131794..80864930 100644 --- a/Filesystem/Filesystem.vbproj +++ b/Filesystem/Filesystem.vbproj @@ -45,7 +45,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll ..\packages\protobuf-net.2.4.0\lib\net40\protobuf-net.dll diff --git a/Filesystem/packages.config b/Filesystem/packages.config index 4c276e2a..c8b3963c 100644 --- a/Filesystem/packages.config +++ b/Filesystem/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/GUIs.ClientSuite/ClientSuite.vbproj b/GUIs.ClientSuite/ClientSuite.vbproj index 2e9cbeb1..3d834188 100644 --- a/GUIs.ClientSuite/ClientSuite.vbproj +++ b/GUIs.ClientSuite/ClientSuite.vbproj @@ -89,7 +89,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll ..\packages\jacobslusser.ScintillaNET.3.6.3\lib\net40\ScintillaNET.dll diff --git a/GUIs.ClientSuite/packages.config b/GUIs.ClientSuite/packages.config index 55fed1f5..22b3f7df 100644 --- a/GUIs.ClientSuite/packages.config +++ b/GUIs.ClientSuite/packages.config @@ -3,6 +3,6 @@ - + \ No newline at end of file diff --git a/Jobs/Jobs.vbproj b/Jobs/Jobs.vbproj index 1abe730c..da12e083 100644 --- a/Jobs/Jobs.vbproj +++ b/Jobs/Jobs.vbproj @@ -108,7 +108,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/Jobs/packages.config b/Jobs/packages.config index 9204b8da..7a05eafe 100644 --- a/Jobs/packages.config +++ b/Jobs/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Message/Messaging.vbproj b/Message/Messaging.vbproj index a396cfbb..a26b52c0 100644 --- a/Message/Messaging.vbproj +++ b/Message/Messaging.vbproj @@ -51,7 +51,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll ..\packages\S22.Imap.3.6.0.0\lib\net40\S22.Imap.dll diff --git a/Message/packages.config b/Message/packages.config index 61e0c253..bbb74850 100644 --- a/Message/packages.config +++ b/Message/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Modules.Config/Config.vbproj b/Modules.Config/Config.vbproj index 7d7203f6..68e2431c 100644 --- a/Modules.Config/Config.vbproj +++ b/Modules.Config/Config.vbproj @@ -45,7 +45,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/Modules.Config/packages.config b/Modules.Config/packages.config index f89fa324..99e34262 100644 --- a/Modules.Config/packages.config +++ b/Modules.Config/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Modules.Database/Database.vbproj b/Modules.Database/Database.vbproj index 4188cab7..03ceee90 100644 --- a/Modules.Database/Database.vbproj +++ b/Modules.Database/Database.vbproj @@ -59,7 +59,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll P:\Visual Studio Projekte\Bibliotheken\Oracle.ManagedDataAccess.dll diff --git a/Modules.Database/packages.config b/Modules.Database/packages.config index 81ef80e4..7fbd4098 100644 --- a/Modules.Database/packages.config +++ b/Modules.Database/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/Modules.Interfaces/Interfaces.vbproj b/Modules.Interfaces/Interfaces.vbproj index 324231de..0b79cf85 100644 --- a/Modules.Interfaces/Interfaces.vbproj +++ b/Modules.Interfaces/Interfaces.vbproj @@ -45,7 +45,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/Modules.Interfaces/packages.config b/Modules.Interfaces/packages.config index f89fa324..99e34262 100644 --- a/Modules.Interfaces/packages.config +++ b/Modules.Interfaces/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Modules.License/License.vbproj b/Modules.License/License.vbproj index 8254f7c8..09db248a 100644 --- a/Modules.License/License.vbproj +++ b/Modules.License/License.vbproj @@ -45,7 +45,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/Modules.License/packages.config b/Modules.License/packages.config index f89fa324..99e34262 100644 --- a/Modules.License/packages.config +++ b/Modules.License/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Modules.Logging/Logging.vbproj b/Modules.Logging/Logging.vbproj index 50b39156..626bc166 100644 --- a/Modules.Logging/Logging.vbproj +++ b/Modules.Logging/Logging.vbproj @@ -45,7 +45,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/Modules.Logging/packages.config b/Modules.Logging/packages.config index f89fa324..99e34262 100644 --- a/Modules.Logging/packages.config +++ b/Modules.Logging/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Modules.Windream/Windream.vbproj b/Modules.Windream/Windream.vbproj index 0c45f1f1..8e132854 100644 --- a/Modules.Windream/Windream.vbproj +++ b/Modules.Windream/Windream.vbproj @@ -65,7 +65,7 @@ - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/Modules.Windream/packages.config b/Modules.Windream/packages.config index f89fa324..99e34262 100644 --- a/Modules.Windream/packages.config +++ b/Modules.Windream/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Modules/ZooFlow/ClassProfileFilter.vb b/Modules/ZooFlow/ClassProfileFilter.vb new file mode 100644 index 00000000..bb00d69b --- /dev/null +++ b/Modules/ZooFlow/ClassProfileFilter.vb @@ -0,0 +1,483 @@ +Imports System.Drawing +Imports System.Windows.Forms +Imports System.Text.RegularExpressions +Imports DigitalData.Modules.Logging +Imports DigitalData.Modules.Windows +Imports DigitalData.Modules.Language.Utils +Imports DigitalData.Modules.ZooFlow.Params + +Public Class ClassProfileFilter + Private _ProfileTable As DataTable + Private _ProcessTable As DataTable + Private _WindowTable As DataTable + Private _ControlTable As DataTable + Private _Profiles As List(Of ProfileData) + Private _Logger As Logger + Private _TreeView As TreeView + Private _Window As Window + + Public ReadOnly Property Profiles As List(Of ProfileData) + Get + Return _Profiles + End Get + End Property + + Public Sub New(LogConfig As LogConfig, ProfileDatatable As DataTable, ProcessTable As DataTable, WindowDatatable As DataTable, ControlDatatable As DataTable, ImageList As ImageList) + Try + _Logger = LogConfig.GetLogger() + _ProfileTable = ProfileDatatable + _ProcessTable = ProcessTable + _WindowTable = WindowDatatable + _ControlTable = ControlDatatable + _Profiles = TransformProfiles() + _Window = New Window(LogConfig) + + _TreeView.Nodes.Clear() + _TreeView.ImageList = ImageList + _TreeView.SelectedImageIndex = 0 + Catch ex As Exception + _Logger.Error(ex) + Throw ex + End Try + End Sub + + Public Function ToList() As List(Of ProfileData) + Return _Profiles + End Function + + Private Function FindNode(ByVal Node As TreeNode, SearchTerm As String) + Dim oNode As TreeNode + For Each oNode In Node.Nodes + If oNode.Text = SearchTerm Then + Return oNode + End If + Next + Return Node + End Function + + Private Function GetLowestNode(ByVal Node As TreeNode) As TreeNode + If Node.GetNodeCount(False) = 1 Then + Return GetLowestNode(Node.Nodes.Item(0)) + Else + Return Node + End If + End Function + + Public Function FilterProfilesByClipboardRegex(Profiles As List(Of ProfileData), ClipboardContents As String) As List(Of ProfileData) + Dim oFilteredProfiles As New List(Of ProfileData) + For Each oProfile In Profiles + _Logger.Debug("Current Profile: {0}", oProfile.Name) + + Try + Dim oRegex As New Regex(oProfile.Regex) + Dim oMatch = oRegex.Match(ClipboardContents) + If oMatch.Success Then + _Logger.Debug("FilterProfilesByClipboardRegex: Clipboard Regex Matched: {0}", ClipboardContents) + 'TODO: Add Debug Data + oFilteredProfiles.Add(oProfile) + oProfile.IsMatched = True + Dim oNode As New TreeNode($"Profile: {oProfile.Name}") + oNode.ImageIndex = 0 + Dim f = New Font("Tahoma", 9, FontStyle.Bold) + oNode.NodeFont = f + _TreeView.Nodes.Add(oNode) + Dim oSubnode As New TreeNode($"MATCH on Global Clipboard Regex: {oProfile.Regex}") + oSubnode.ImageIndex = 1 + oSubnode.Tag = oProfile.Name & "-REGEX" + oNode.Nodes.Add(oSubnode) + + End If + Catch ex As Exception + _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oProfile.Regex, ClipboardContents) + _Logger.Error(ex) + End Try + Next + + Return oFilteredProfiles + End Function + Public Function FilterProfilesByProcess(Profiles As List(Of ProfileData), CurrentProcessName As String) As List(Of ProfileData) + Dim oFilteredProfiles As New List(Of ProfileData) + Try + For Each oProfile In Profiles + Dim oGuid = oProfile.Guid + + If oProfile.IsMatched = False Then + Continue For + End If + + + Dim oProcesses As New List(Of ProfileData.ProcessData) + For Each oProcessDef As ProfileData.ProcessData In oProfile.Processes + If oProcessDef.ProfileId <> oGuid Then + Continue For + End If + _Logger.Debug($"FilterProfilesByProcess: Checking Profile: {oProfile.Name} ...") + If oProcessDef.ProcessName.ToLower = CurrentProcessName.ToLower Then + _Logger.Debug($"Yes...Processname Matched: {oProcessDef.ProcessName}") + 'oProfile.MATCH_PROCESSNAME = $"Processname Matched: {oProfile.ProcessName}" + 'TODO: Add Debug Data + oFilteredProfiles.Add(oProfile) + oProfile.MatchedProcessID = oProcessDef.Guid + oProcessDef.IsMatched = True + oProcesses.Add(oProcessDef) + oProfile.IsMatched = True + oProfile.MatchedProcessID = oProcessDef.Guid + Dim oParentNode As TreeNode + Dim oExit = False + For Each oTreeNode As TreeNode In _TreeView.Nodes + For Each oNodes As TreeNode In oTreeNode.Nodes + If oExit = True Then Exit For + If oNodes.Tag = oProfile.Name & "-REGEX" Then + oParentNode = oNodes + oExit = True + Exit For + End If + Next + Next + + If Not IsNothing(oParentNode) Then + Dim oNode As New TreeNode($"MATCH on Process: {oProcessDef.ProcessName}") + oNode.ImageIndex = 4 + oNode.Tag = oProfile.Name & "-PROCESS" + oParentNode.Nodes.Add(oNode) + End If + End If + Next + If oFilteredProfiles.Count > 0 Then + oProfile.Processes = oProcesses + End If + Next + + Return oFilteredProfiles + Catch ex As Exception + _Logger.Warn("Unexpected error in FilterProfilesByProcess...") + _Logger.Error(ex) + End Try + + End Function + Public Function FilterWindowsByWindowTitleRegex(Profiles As List(Of ProfileData), WindowTitle As String) As List(Of ProfileData) + Dim oProfiles As New List(Of ProfileData) + + For Each oProfile As ProfileData In Profiles + _Logger.Debug("Checking WindowDefinition for profile: {0}...", oProfile.Name) + If oProfile.IsMatched = False Then Continue For + Dim oWindows As New List(Of ProfileData.WindowData) + + For Each oWindowDef As ProfileData.WindowData In oProfile.Windows + If oWindowDef.WindowProcessID <> oProfile.MatchedProcessID Then Continue For + Try + If oWindowDef.Regex = String.Empty Then + oProfile.MatchedWindowID = oWindowDef.Guid + oWindowDef.IsMatched = True + oWindows.Add(oWindowDef) + Exit For + End If + + Dim oRegex As New Regex(oWindowDef.Regex) + Dim oMatch = oRegex.Match(WindowTitle) + + If oMatch.Success Then + _Logger.Debug("MATCH on WindowTitle: {0}", WindowTitle) + 'TODO: Add Debug Data + oProfile.MatchedWindowID = oWindowDef.Guid + oWindowDef.IsMatched = True + oWindows.Add(oWindowDef) + Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfile.Name & "-REGEX") + If Not IsNothing(olowestNode) Then + Dim oNode As New TreeNode($"MATCH on WindowTitle: [{WindowTitle}]") + oNode.ImageIndex = 3 + oNode.Tag = oProfile.Name & "-WINDOW" + olowestNode.Nodes.Add(oNode) + End If + Exit For + End If + Catch ex As Exception + _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oWindowDef.Regex, WindowTitle) + _Logger.Error(ex) + End Try + Next + + If oWindows.Count > 0 Then + oProfile.Windows = oWindows + oProfile.IsMatched = True + oProfiles.Add(oProfile) + End If + Next + + Return oProfiles + End Function + + Public Function FilterWindowsByWindowClipboardRegex(Profiles As List(Of ProfileData), ClipboardContents As String) As List(Of ProfileData) + Dim oProfiles As New List(Of ProfileData) + + For Each oProfile As ProfileData In Profiles + _Logger.Debug("Current Profile: {0}", oProfile.Name) + + Dim oWindows As New List(Of ProfileData.WindowData) + + For Each w As ProfileData.WindowData In oProfile.Windows + Try + If w.Regex = String.Empty Then + oWindows.Add(w) + End If + + Dim oRegex As New Regex(w.Regex) + Dim oMatch = oRegex.Match(ClipboardContents) + + If oMatch.Success Then + _Logger.Debug("Window Clipboard Regex Matched: {0}", ClipboardContents) + Dim oResult As TreeNode + For Each oTreeNode In _TreeView.Nodes + If Not IsNothing(oResult) Then Exit For + If oTreeNode.Tag = oProfile.Name & "-REGEX" Then + oResult = oTreeNode + End If + + + Next + If Not IsNothing(oResult) Then + Dim oNode As New TreeNode($"MATCH on WINDOW Clipboard Regex: [{w.Regex}]") + oNode.ImageIndex = 2 + oNode.Tag = oProfile.Name & "-WINDOW_REGEX" + Dim olowestNode As TreeNode = GetLowestNode(oResult) + olowestNode.Nodes.Add(oNode) + End If + + oWindows.Add(w) + + + End If + Catch ex As Exception + _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", w.Regex, ClipboardContents) + _Logger.Error(ex) + End Try + Next + + If oWindows.Count > 0 Then + oProfile.Windows = oWindows + oProfiles.Add(oProfile) + End If + Next + + Return oProfiles + End Function + + Public Function FilterProfilesByFocusedControl(Profiles As List(Of ProfileData), ClipboardContents As String, ControlFocusresult As String) As List(Of ProfileData) + Dim oWindow As Window.WindowInfo + Dim oFocusedControl As Window.WindowInfo + Dim oFocusedControlName As String = String.Empty + + Try + oWindow = _Window.GetWindowInfo() + oFocusedControl = _Window.GetFocusedControl(oWindow.hWnd) + + If oFocusedControl Is Nothing Then + _Logger.Info("Could not get FocusedControl in Window (Old method) {0}", oWindow.WindowTitle) + oFocusedControlName = String.Empty + Else + oFocusedControlName = oFocusedControl.ControlName + End If + Catch ex As Exception + _Logger.Warn("Error while getting Focused control (Old method)") + _Logger.Error(ex) + oFocusedControlName = String.Empty + End Try + + Dim oFilteredProfiles As New List(Of ProfileData) + + For Each oProfileMatchedSofar In Profiles + If oProfileMatchedSofar.IsMatched = False Then Continue For + + _Logger.Debug("Checking ControlDefiniotion on profile: {0}", oProfileMatchedSofar.Name) + If oProfileMatchedSofar.Controls.Count = 0 Then + oFilteredProfiles.Add(oProfileMatchedSofar) + + Dim oNode As New TreeNode($"No Controls configured!") + oNode.ImageIndex = 2 + oNode.ForeColor = Color.Blue + oNode.Tag = oProfileMatchedSofar.Name & "-NOCONTROLCONFIG" + Dim f = New Font("Tahoma", 10, FontStyle.Bold) + oNode.NodeFont = f + _TreeView.Nodes.Add(oNode) + Continue For + End If + + Dim oControls As New List(Of ProfileData.ControlData) + + For Each oControlDefinition In oProfileMatchedSofar.Controls + Try + If oControlDefinition.WindowId <> oProfileMatchedSofar.MatchedWindowID Then Continue For + _Logger.Debug($"Working on ControlDefinition: {oControlDefinition.Guid}-{oControlDefinition.ControlName}...") + If oControlDefinition.Regex = String.Empty Then + oProfileMatchedSofar.MatchedControlID = oControlDefinition.Guid + oControlDefinition.IsMatched = True + oControls.Add(oControlDefinition) + Exit For + End If + 'Dim oResult As TreeNode + 'For Each oTreeNode In CurrMatchTreeView.Nodes + ' oResult = NodeFind(oTreeNode, $"Global Clipboard Regex Matched [{oProfile.Regex}]") + 'Next + 'Dim oNode As TreeNode + Dim oNodeCaption As String + 'Dim oAddNode As Boolean = False + Dim oRegex As New Regex(oControlDefinition.Regex) + + Dim oFocusedControlResult As String = "" + + If oControlDefinition.AutomationId <> String.Empty And oControlDefinition.ControlName = String.Empty Then + _Logger.Debug($"AutomationID should be used...") + If Not IsNothing(ControlFocusresult) Then + If ControlFocusresult <> String.Empty Then + _Logger.Debug($"AutomationID will be used...") + oFocusedControlResult = ControlFocusresult + End If + End If + ElseIf oControlDefinition.AutomationId = String.Empty And oControlDefinition.ControlName <> String.Empty Then + _Logger.Debug($"ControlName should be used...") + If Not IsNothing(oFocusedControlName) Then + If oFocusedControlName <> String.Empty Then + _Logger.Debug($"ControlName will be used...") + oFocusedControlResult = oFocusedControlName + End If + End If + + End If + If oFocusedControlResult <> String.Empty Then + Dim oControlRegex As New Regex(oControlDefinition.Regex) + Dim oControlMatch = oRegex.Match(oFocusedControlResult) + + If oControlMatch.Success Then + _Logger.Debug($"MATCH on Focused Control [{oFocusedControlResult}] with Regex [{oControlDefinition.Regex}]") + oProfileMatchedSofar.IsMatched = True + oProfileMatchedSofar.MatchedControlID = oControlDefinition.Guid + oControlDefinition.IsMatched = True + oControls.Add(oControlDefinition) + Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfileMatchedSofar.Name & "-REGEX") + If Not IsNothing(olowestNode) Then + Dim oNode As New TreeNode($"MATCH on Focused Control [{oFocusedControlResult}] with Regex [{oControlDefinition.Regex}]") + oNode.ImageIndex = 2 + oNode.Tag = oProfileMatchedSofar.Name & "-CONTROL" + olowestNode.Nodes.Add(oNode) + End If + Exit For + End If + End If + Catch ex As Exception + _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oControlDefinition.Regex, oFocusedControlName) + _Logger.Error(ex) + End Try + Next + + If oControls.Count > 0 Then + oProfileMatchedSofar.Controls = oControls + oFilteredProfiles.Add(oProfileMatchedSofar) + Else + Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfileMatchedSofar.Name & "-REGEX") + If Not IsNothing(olowestNode) Then + Dim oNode As New TreeNode($"NO MATCHES on Focused Control, Please check the Config") + oNode.ImageIndex = 2 + oNode.Tag = oProfileMatchedSofar.Name & "-CONTROLNoMatch" + olowestNode.Nodes.Add(oNode) + End If + End If + Next + + Return oFilteredProfiles + End Function + Private Function Node_Get_Lowest_Node(NodeTag As String) As TreeNode + Dim oExit = False + Dim oParentNode As TreeNode + For Each oTreeNode As TreeNode In _TreeView.Nodes + For Each oNodes As TreeNode In oTreeNode.Nodes + If oExit = True Then Exit For + If oNodes.Tag = NodeTag Then + oParentNode = oNodes + oExit = True + Exit For + End If + Next + Next + Dim olowestNode As TreeNode = GetLowestNode(oParentNode) + + Return olowestNode + End Function + Public Function ClearNotMatchedProfiles(Profiles As List(Of ProfileData)) As List(Of ProfileData) + Dim oFilteredProfiles As New List(Of ProfileData) + For Each oProfile In Profiles + If oProfile.IsMatched Then + oFilteredProfiles.Add(oProfile) + End If + Next + Return oFilteredProfiles + End Function + Private Function TransformProfiles() As List(Of ProfileData) + Dim oList As New List(Of ProfileData) + + For Each oRow As DataRow In _ProfileTable.Rows + Dim oProfileId = oRow.Item("GUID") + Dim oProcessList As List(Of ProfileData.ProcessData) = TransformProcesses(oProfileId, _ProcessTable) + Dim oWindowList As List(Of ProfileData.WindowData) = TransformWindows(oProfileId, _WindowTable) + Dim oControlList As List(Of ProfileData.ControlData) = TransformControls(oProfileId, _ControlTable) + + oList.Add(New ProfileData() With { + .Guid = oRow.Item("GUID"), + .Regex = NotNull(oRow.Item("REGEX_EXPRESSION"), String.Empty), + .Name = NotNull(oRow.Item("NAME"), String.Empty), + .Comment = NotNull(oRow.Item("COMMENT"), String.Empty), + .ProfileType = NotNull(oRow.Item("PROFILE_TYPE"), String.Empty), + .Processes = oProcessList, + .Windows = oWindowList, + .Controls = oControlList + }) + Next + + Return oList + End Function + + Private Function TransformControls(ProfileId As Integer, ControlDatatable As DataTable) As List(Of ProfileData.ControlData) + Dim oControlList As New List(Of ProfileData.ControlData) + + For Each oRow As DataRow In ControlDatatable.Rows + If oRow.Item("PROFILE_ID") = ProfileId Then + oControlList.Add(New ProfileData.ControlData() With { + .Guid = oRow.Item("GUID"), + .Description = NotNull(oRow.Item("DESCRIPTION"), String.Empty), + .Regex = NotNull(oRow.Item("REGEX"), String.Empty), + .AutomationId = NotNull(oRow.Item("AUTOMATION_ID"), String.Empty), + .WindowId = oRow.Item("WINDOW_ID") + }) + End If + Next + + Return oControlList + End Function + Private Function TransformProcesses(ProfileId As Integer, ProcessDatatable As DataTable) As List(Of ProfileData.ProcessData) + Dim oProcessList As New List(Of ProfileData.ProcessData) + + For Each oRow As DataRow In ProcessDatatable.Rows + oProcessList.Add(New ProfileData.ProcessData() With { + .Guid = oRow.Item("GUID"), + .ProfileId = oRow.Item("PROFILE_ID"), + .ProcessName = NotNull(oRow.Item("PROC_NAME"), String.Empty) + }) + Next + + Return oProcessList + End Function + Private Function TransformWindows(ProfileId As Integer, WindowDatatable As DataTable) As List(Of ProfileData.WindowData) + Dim oWindowList As New List(Of ProfileData.WindowData) + + For Each oRow As DataRow In WindowDatatable.Rows + oWindowList.Add(New ProfileData.WindowData() With { + .Guid = oRow.Item("GUID"), + .WindowProcessID = oRow.Item("PROCESS_ID"), + .Title = NotNull(oRow.Item("DESCRIPTION"), String.Empty), + .Regex = NotNull(oRow.Item("REGEX"), String.Empty), + .Sequence = NotNull(oRow.Item("SEQUENCE"), 0) + }) + Next + + Return oWindowList + End Function +End Class diff --git a/Modules/ZooFlow/Environment.vb b/Modules/ZooFlow/Environment.vb new file mode 100644 index 00000000..d1f27769 --- /dev/null +++ b/Modules/ZooFlow/Environment.vb @@ -0,0 +1,4 @@ +Public Class Environment + Public User As State.UserState + Public Modules As Dictionary(Of String, State.ModuleState) +End Class diff --git a/Modules/ZooFlow/My Project/Application.Designer.vb b/Modules/ZooFlow/My Project/Application.Designer.vb new file mode 100644 index 00000000..8ab460ba --- /dev/null +++ b/Modules/ZooFlow/My Project/Application.Designer.vb @@ -0,0 +1,13 @@ +'------------------------------------------------------------------------------ +' +' Dieser Code wurde von einem Tool generiert. +' Laufzeitversion:4.0.30319.42000 +' +' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +' der Code erneut generiert wird. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + diff --git a/Modules/ZooFlow/My Project/Application.myapp b/Modules/ZooFlow/My Project/Application.myapp new file mode 100644 index 00000000..758895de --- /dev/null +++ b/Modules/ZooFlow/My Project/Application.myapp @@ -0,0 +1,10 @@ + + + false + false + 0 + true + 0 + 1 + true + diff --git a/Modules/ZooFlow/My Project/AssemblyInfo.vb b/Modules/ZooFlow/My Project/AssemblyInfo.vb new file mode 100644 index 00000000..2f371237 --- /dev/null +++ b/Modules/ZooFlow/My Project/AssemblyInfo.vb @@ -0,0 +1,35 @@ +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' Allgemeine Informationen über eine Assembly werden über die folgenden +' Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +' die einer Assembly zugeordnet sind. + +' Werte der Assemblyattribute überprüfen + + + + + + + + + + +'Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird. + + +' Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +' +' Hauptversion +' Nebenversion +' Buildnummer +' Revision +' +' Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, +' übernehmen, indem Sie "*" eingeben: +' + + + diff --git a/Modules/ZooFlow/My Project/Resources.Designer.vb b/Modules/ZooFlow/My Project/Resources.Designer.vb new file mode 100644 index 00000000..7f80f5d1 --- /dev/null +++ b/Modules/ZooFlow/My Project/Resources.Designer.vb @@ -0,0 +1,63 @@ +'------------------------------------------------------------------------------ +' +' Dieser Code wurde von einem Tool generiert. +' Laufzeitversion:4.0.30319.42000 +' +' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +' der Code erneut generiert wird. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + +Imports System + +Namespace My.Resources + + 'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + '-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + 'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + 'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + ''' + ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + ''' + _ + Friend Module Resources + + Private resourceMan As Global.System.Resources.ResourceManager + + Private resourceCulture As Global.System.Globalization.CultureInfo + + ''' + ''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + ''' + _ + 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("DigitalData.Modules.ZooFlow.Resources", GetType(Resources).Assembly) + resourceMan = temp + End If + Return resourceMan + End Get + End Property + + ''' + ''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + ''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + ''' + _ + Friend Property Culture() As Global.System.Globalization.CultureInfo + Get + Return resourceCulture + End Get + Set + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/Modules/ZooFlow/My Project/Resources.resx b/Modules/ZooFlow/My Project/Resources.resx new file mode 100644 index 00000000..af7dbebb --- /dev/null +++ b/Modules/ZooFlow/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/Modules/ZooFlow/My Project/Settings.Designer.vb b/Modules/ZooFlow/My Project/Settings.Designer.vb new file mode 100644 index 00000000..69590c62 --- /dev/null +++ b/Modules/ZooFlow/My Project/Settings.Designer.vb @@ -0,0 +1,73 @@ +'------------------------------------------------------------------------------ +' +' Dieser Code wurde von einem Tool generiert. +' Laufzeitversion:4.0.30319.42000 +' +' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +' der Code erneut generiert wird. +' +'------------------------------------------------------------------------------ + +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 "Automatische My.Settings-Speicherfunktion" +#If _MyType = "WindowsForms" Then + Private Shared addedHandler As Boolean + + Private Shared addedHandlerLockObject As New Object + + _ + Private Shared Sub AutoSaveSettings(sender As Global.System.Object, 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.DigitalData.Modules.ZooFlow.My.MySettings + Get + Return Global.DigitalData.Modules.ZooFlow.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/Modules/ZooFlow/My Project/Settings.settings b/Modules/ZooFlow/My Project/Settings.settings new file mode 100644 index 00000000..85b890b3 --- /dev/null +++ b/Modules/ZooFlow/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Modules/ZooFlow/Params/ClipboardWatcherParams.vb b/Modules/ZooFlow/Params/ClipboardWatcherParams.vb new file mode 100644 index 00000000..9c4e4897 --- /dev/null +++ b/Modules/ZooFlow/Params/ClipboardWatcherParams.vb @@ -0,0 +1,5 @@ +Imports DigitalData.Modules.ZooFlow.Params + +Public Class ClipboardWatcherParams + Public MatchingProfiles As List(Of ProfileData) +End Class diff --git a/Modules/ZooFlow/Params/ProfileData.vb b/Modules/ZooFlow/Params/ProfileData.vb new file mode 100644 index 00000000..3d03fd4b --- /dev/null +++ b/Modules/ZooFlow/Params/ProfileData.vb @@ -0,0 +1,47 @@ +Namespace Params + Public Class ProfileData + Public Guid As Integer + Public Regex As String + Public Name As String + Public Comment As String + Public ProfileType As Integer + + Public Processes As List(Of ProfileData.ProcessData) + Public Windows As List(Of ProfileData.WindowData) + Public Controls As List(Of ProfileData.ControlData) + + Public CountDocs As Integer = 0 + Public CountData As Integer = 0 + Public IsMatched As Boolean = False + Public MatchedProcessID As Integer = 0 + Public MatchedWindowID As Integer = 0 + Public MatchedControlID As Integer = 0 + Public SelectCommand As String + + Public Class ProcessData + Public Guid As Integer + Public ProfileId As Integer + Public ProcessName As String + Public IsMatched As Boolean = False + End Class + + Public Class ControlData + Public Guid As Integer + Public WindowId As Integer + Public Description As String + Public Regex As String + Public AutomationId As String + Public ControlName As String + Public IsMatched As Boolean = False + End Class + + Public Class WindowData + Public Guid As Integer + Public WindowProcessID As Integer + Public Title As String + Public Regex As String + Public Sequence As Integer + Public IsMatched As Boolean = False + End Class + End Class +End Namespace \ No newline at end of file diff --git a/Modules/ZooFlow/State/ModuleState.vb b/Modules/ZooFlow/State/ModuleState.vb new file mode 100644 index 00000000..9f960d5f --- /dev/null +++ b/Modules/ZooFlow/State/ModuleState.vb @@ -0,0 +1,7 @@ +Namespace State + Public Class ModuleState + Public Property HasAccess As Boolean + Public Property IsAdmin As Boolean + Public Property LoggedIn As Integer + End Class +End Namespace \ No newline at end of file diff --git a/Modules/ZooFlow/State/ServiceState.vb b/Modules/ZooFlow/State/ServiceState.vb new file mode 100644 index 00000000..34743015 --- /dev/null +++ b/Modules/ZooFlow/State/ServiceState.vb @@ -0,0 +1,6 @@ +Namespace State + Public Class ServiceState + Public Property Online As Boolean = True + Public Property LastChecked As DateTime = DateTime.Now + End Class +End Namespace \ No newline at end of file diff --git a/Modules/ZooFlow/State/UserState.vb b/Modules/ZooFlow/State/UserState.vb new file mode 100644 index 00000000..f382a9f2 --- /dev/null +++ b/Modules/ZooFlow/State/UserState.vb @@ -0,0 +1,28 @@ +Imports System.Threading + +Namespace State + ''' + ''' Helper Class to hold User State + ''' + Public Class UserState + Public Property UserId As Integer + Public Property UserName As String + Public Property Surname As String + Public Property GivenName As String + Public Property ShortName As String + Public Property Email As String + Public Property MachineName As String + Public Property DateFormat As String + Public Property Language As String + + ''' + ''' Initialize user object with values that can be read from the environment + ''' + Public Sub New() + Language = Thread.CurrentThread.CurrentCulture.Name + UserName = System.Environment.UserName + MachineName = System.Environment.MachineName + End Sub + End Class +End Namespace + diff --git a/Modules/ZooFlow/ZooFlow.vbproj b/Modules/ZooFlow/ZooFlow.vbproj new file mode 100644 index 00000000..53da6caa --- /dev/null +++ b/Modules/ZooFlow/ZooFlow.vbproj @@ -0,0 +1,135 @@ + + + + + Debug + AnyCPU + {81CAC44F-3711-4C8F-AE98-E02A7448782A} + Library + DigitalData.Modules.ZooFlow + DigitalData.Modules.ZooFlow + 512 + Windows + v4.6.1 + + + true + full + true + true + bin\Debug\ + DigitalData.Modules.ZooFlow.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + pdbonly + false + true + true + bin\Release\ + DigitalData.Modules.ZooFlow.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + On + + + Binary + + + Off + + + On + + + + + ..\..\packages\NLog.4.6.7\lib\net45\NLog.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + Application.myapp + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + + + + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + Designer + + + + + MyApplicationCodeGenerator + Application.Designer.vb + + + SettingsSingleFileGenerator + My + Settings.Designer.vb + + + + + + {d3c8cfed-d6f6-43a8-9bdf-454145d0352f} + Language + + + {903B2D7D-3B80-4BE9-8713-7447B704E1B0} + Logging + + + {5EFAEF9B-90B9-4F05-9F70-F79AD77FFF86} + Windows + + + + \ No newline at end of file diff --git a/Modules/ZooFlow/packages.config b/Modules/ZooFlow/packages.config new file mode 100644 index 00000000..99e34262 --- /dev/null +++ b/Modules/ZooFlow/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Products.ClipboardWatcher/ClipboardWatcher.vbproj b/Products.ClipboardWatcher/ClipboardWatcher.vbproj index 9d6dd701..a40ca953 100644 --- a/Products.ClipboardWatcher/ClipboardWatcher.vbproj +++ b/Products.ClipboardWatcher/ClipboardWatcher.vbproj @@ -43,9 +43,25 @@ On + + + + + + + + ..\packages\NLog.4.6.7\lib\net45\NLog.dll + + + + + + + + @@ -91,6 +107,7 @@ frmMatch.vb + VbMyResourcesResXFileCodeGenerator Resources.Designer.vb @@ -108,6 +125,7 @@ My Settings.Designer.vb + @@ -118,14 +136,22 @@ {eaf0ea75-5fa7-485d-89c7-b2d843b03a96} Database + + {d3c8cfed-d6f6-43a8-9bdf-454145d0352f} + Language + {903b2d7d-3b80-4be9-8713-7447b704e1b0} Logging - - {D0FB36EB-783D-40E1-B71E-A0B84B2FE567} + + {81cac44f-3711-4c8f-ae98-e02a7448782a} ZooFlow + + {5EFAEF9B-90B9-4F05-9F70-F79AD77FFF86} + Windows + \ No newline at end of file diff --git a/Products.ClipboardWatcher/My Project/licenses.licx b/Products.ClipboardWatcher/My Project/licenses.licx new file mode 100644 index 00000000..ed708931 --- /dev/null +++ b/Products.ClipboardWatcher/My Project/licenses.licx @@ -0,0 +1 @@ +DevExpress.XtraEditors.TileControl, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a diff --git a/Products.ClipboardWatcher/frmMatch.Designer.vb b/Products.ClipboardWatcher/frmMatch.Designer.vb index 8f1a19c0..7258bcab 100644 --- a/Products.ClipboardWatcher/frmMatch.Designer.vb +++ b/Products.ClipboardWatcher/frmMatch.Designer.vb @@ -22,16 +22,78 @@ Partial Class frmMatch 'Das Bearbeiten mit dem Code-Editor ist nicht möglich. _ Private Sub InitializeComponent() + Me.TileControlMatch = New DevExpress.XtraEditors.TileControl() + Me.TileGroupDocumentsData = New DevExpress.XtraEditors.TileGroup() + Me.TileGroupDocuments = New DevExpress.XtraEditors.TileGroup() + Me.TileGroupData = New DevExpress.XtraEditors.TileGroup() + Me.Label1 = New System.Windows.Forms.Label() Me.SuspendLayout() ' + 'TileControlMatch + ' + Me.TileControlMatch.AllowDragTilesBetweenGroups = False + Me.TileControlMatch.AppearanceGroupText.BackColor = System.Drawing.Color.Transparent + Me.TileControlMatch.AppearanceGroupText.Font = New System.Drawing.Font("Segoe UI", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) + Me.TileControlMatch.AppearanceGroupText.ForeColor = System.Drawing.Color.White + Me.TileControlMatch.AppearanceGroupText.Options.UseBackColor = True + Me.TileControlMatch.AppearanceGroupText.Options.UseFont = True + Me.TileControlMatch.AppearanceGroupText.Options.UseForeColor = True + Me.TileControlMatch.BackColor = System.Drawing.Color.FromArgb(CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer)) + Me.TileControlMatch.Dock = System.Windows.Forms.DockStyle.Fill + Me.TileControlMatch.Groups.Add(Me.TileGroupDocumentsData) + Me.TileControlMatch.Groups.Add(Me.TileGroupDocuments) + Me.TileControlMatch.Groups.Add(Me.TileGroupData) + Me.TileControlMatch.Location = New System.Drawing.Point(0, 0) + Me.TileControlMatch.Name = "TileControlMatch" + Me.TileControlMatch.ShowGroupText = True + Me.TileControlMatch.Size = New System.Drawing.Size(800, 450) + Me.TileControlMatch.TabIndex = 0 + Me.TileControlMatch.Text = "TileControl1" + ' + 'TileGroupDocumentsData + ' + Me.TileGroupDocumentsData.Name = "TileGroupDocumentsData" + Me.TileGroupDocumentsData.Text = "Kombiniert" + ' + 'TileGroupDocuments + ' + Me.TileGroupDocuments.Name = "TileGroupDocuments" + Me.TileGroupDocuments.Text = "Dokumente" + ' + 'TileGroupData + ' + Me.TileGroupData.Name = "TileGroupData" + Me.TileGroupData.Text = "Daten" + ' + 'Label1 + ' + Me.Label1.AutoSize = True + Me.Label1.BackColor = System.Drawing.Color.FromArgb(CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer)) + Me.Label1.Font = New System.Drawing.Font("Segoe UI Semibold", 12.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) + Me.Label1.ForeColor = System.Drawing.Color.White + Me.Label1.Location = New System.Drawing.Point(12, 9) + Me.Label1.Name = "Label1" + Me.Label1.Size = New System.Drawing.Size(401, 21) + Me.Label1.TabIndex = 1 + Me.Label1.Text = "Es wurde mehr als ein Match für Ihre Suche gefunden:" + ' 'frmMatch ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.ClientSize = New System.Drawing.Size(800, 450) + Me.Controls.Add(Me.Label1) + Me.Controls.Add(Me.TileControlMatch) Me.Name = "frmMatch" Me.Text = "frmMatch" Me.ResumeLayout(False) + Me.PerformLayout() End Sub + + Friend WithEvents TileControlMatch As DevExpress.XtraEditors.TileControl + Friend WithEvents TileGroupDocumentsData As DevExpress.XtraEditors.TileGroup + Friend WithEvents TileGroupDocuments As DevExpress.XtraEditors.TileGroup + Friend WithEvents TileGroupData As DevExpress.XtraEditors.TileGroup + Friend WithEvents Label1 As Windows.Forms.Label End Class diff --git a/Products.ClipboardWatcher/frmMatch.vb b/Products.ClipboardWatcher/frmMatch.vb index 0000349a..673e6e22 100644 --- a/Products.ClipboardWatcher/frmMatch.vb +++ b/Products.ClipboardWatcher/frmMatch.vb @@ -1,5 +1,11 @@ -Imports DigitalData.Modules.Logging -Imports ZooFlow +Imports System.Drawing +Imports System.Windows.Forms +Imports DevExpress.XtraEditors +Imports DigitalData.Modules.Logging +Imports DigitalData.Modules.Windows +Imports DigitalData.Modules.ZooFlow +Imports DigitalData.Modules.ZooFlow.Params + ''' ''' ''' Selfcontained: @@ -16,15 +22,134 @@ Imports ZooFlow ''' - Clipboard Content as String ''' Public Class frmMatch - Public Sub New(LogConfig As LogConfig, Environment As ClassEnvironment) + Private _LogConfig As LogConfig + Private _Logger As Logger + Private _Environment As Environment + Private _Params As ClipboardWatcherParams + + Private PrimaryFont As New Font("Segoe UI", 12, FontStyle.Bold) + Private SecondaryFont As New Font("Segoe UI", 10) + + Private Const NO_COUNT_SQL As Integer = 99998 + Private Const INVALID_COUNT_SQL As Integer = 99999 + + Private Enum ProfileType + ANY = 0 + DOCS_ONLY = 1 + DATA_ONLY = 2 + End Enum + + Public Sub New(LogConfig As LogConfig, Environment As Environment, Params As ClipboardWatcherParams) ' Dieser Aufruf ist für den Designer erforderlich. InitializeComponent() ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu. - + _LogConfig = LogConfig + _Logger = LogConfig.GetLogger() + _Environment = Environment + _Params = Params End Sub Private Sub frmMatch_Load(sender As Object, e As EventArgs) Handles MyBase.Load + Dim oCreatedTiles = CreateTiles() + If oCreatedTiles = -1 Then + Exit Sub + End If End Sub + + Function CreateTiles() As Integer + Try + Dim oCreatedTiles As Integer = 0 + Dim oDocumentGroup = TileControlMatch.Groups.Item("TileGroupDocuments") + Dim oDataGroup = TileControlMatch.Groups.Item("TileGroupData") + Dim oDataDocumentsGroup = TileControlMatch.Groups.Item("TileGroupDocumentsData") + + oDocumentGroup.Items.Clear() + oDataGroup.Items.Clear() + + For Each oProfile As ProfileData In _Params.MatchingProfiles + If oProfile.ProfileType = ProfileType.ANY Then + If oProfile.CountData > 0 And oProfile.CountDocs > 0 Then + Dim oCountText = oProfile.CountData + oProfile.CountDocs + Dim oItem = CreateTile(oProfile, $"{oCountText} Ergebnisse") + oDataDocumentsGroup.Items.Add(oItem) + oCreatedTiles += 1 + End If + End If + + If oProfile.ProfileType = ProfileType.ANY Or oProfile.ProfileType = ProfileType.DOCS_ONLY Then + If oProfile.CountDocs > 0 Then + Dim oItem = CreateTile(oProfile, $"{oProfile.CountDocs} Dokumente") + oDocumentGroup.Items.Add(oItem) + oCreatedTiles += 1 + End If + End If + + If oProfile.ProfileType = ProfileType.ANY Or oProfile.ProfileType = ProfileType.DATA_ONLY Then + If oProfile.CountData > 0 Then + Dim oItem = CreateTile(oProfile, $"{oProfile.CountData} Datensätze") + oDataGroup.Items.Add(oItem) + oCreatedTiles += 1 + End If + End If + Next + + Return oCreatedTiles + Catch ex As Exception + _Logger.Error(ex) + MsgBox("Error while creating profile tiles!" & vbNewLine & ex.Message) + Return -1 + End Try + End Function + + Private Function CreateTile(Profile As ProfileData, CountText As String) As TileItem + Dim oItem As New TileItem() With {.Tag = Profile.Guid} + oItem.Elements.Clear() + + Dim oNameElement = New TileItemElement With { + .Text = Profile.Name, + .TextAlignment = TileItemContentAlignment.TopLeft + } + oNameElement.Appearance.Normal.Font = PrimaryFont + oItem.Elements.Add(oNameElement) + + Dim oCommentElement = New TileItemElement With { + .Text = Profile.Comment, + .TextAlignment = TileItemContentAlignment.MiddleLeft + } + oCommentElement.Appearance.Normal.Font = SecondaryFont + oItem.Elements.Add(oCommentElement) + + Dim oCountElement = New TileItemElement With { + .Text = GetCountText(Profile, CountText), + .TextAlignment = TileItemContentAlignment.BottomRight + } + oCountElement.Appearance.Normal.Font = SecondaryFont + oItem.Elements.Add(oCountElement) + + Return oItem + End Function + + Private Function GetCountText(Profile As ProfileData, CountText As String) As String + Dim oText As String = "No implemented" + + If Profile.CountData = INVALID_COUNT_SQL Then + oText = "Invalid SQL!" + ElseIf Profile.CountData = NO_COUNT_SQL Then + oText = "No SQL!" + Else + oText = CountText + End If + + If Profile.CountDocs = INVALID_COUNT_SQL Then + oText = "Invalid SQL!" + ElseIf Profile.CountDocs = NO_COUNT_SQL Then + oText = "No SQL!" + Else + oText = CountText + End If + + Return oText + End Function End Class diff --git a/Products.ClipboardWatcher/packages.config b/Products.ClipboardWatcher/packages.config new file mode 100644 index 00000000..99e34262 --- /dev/null +++ b/Products.ClipboardWatcher/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/SERVICES/DDEDM_NetworkService/IDBService.vbproj b/SERVICES/DDEDM_NetworkService/IDBService.vbproj index 67e168a5..90e096ee 100644 --- a/SERVICES/DDEDM_NetworkService/IDBService.vbproj +++ b/SERVICES/DDEDM_NetworkService/IDBService.vbproj @@ -52,7 +52,7 @@ - ..\..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\..\packages\NLog.4.6.7\lib\net45\NLog.dll diff --git a/SERVICES/DDEDM_NetworkService/packages.config b/SERVICES/DDEDM_NetworkService/packages.config index 9204b8da..7a05eafe 100644 --- a/SERVICES/DDEDM_NetworkService/packages.config +++ b/SERVICES/DDEDM_NetworkService/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Service.JobRunner/JobRunner.vbproj b/Service.JobRunner/JobRunner.vbproj index aa9af41c..7df7004d 100644 --- a/Service.JobRunner/JobRunner.vbproj +++ b/Service.JobRunner/JobRunner.vbproj @@ -52,7 +52,7 @@ - ..\packages\NLog.4.6.2\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll ..\packages\Quartz.3.0.7\lib\net452\Quartz.dll diff --git a/Service.JobRunner/packages.config b/Service.JobRunner/packages.config index 2f67f3fc..c2fb6688 100644 --- a/Service.JobRunner/packages.config +++ b/Service.JobRunner/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Windows/My Project/Application.Designer.vb b/Windows/My Project/Application.Designer.vb new file mode 100644 index 00000000..8ab460ba --- /dev/null +++ b/Windows/My Project/Application.Designer.vb @@ -0,0 +1,13 @@ +'------------------------------------------------------------------------------ +' +' Dieser Code wurde von einem Tool generiert. +' Laufzeitversion:4.0.30319.42000 +' +' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +' der Code erneut generiert wird. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + diff --git a/Windows/My Project/Application.myapp b/Windows/My Project/Application.myapp new file mode 100644 index 00000000..758895de --- /dev/null +++ b/Windows/My Project/Application.myapp @@ -0,0 +1,10 @@ + + + false + false + 0 + true + 0 + 1 + true + diff --git a/Windows/My Project/AssemblyInfo.vb b/Windows/My Project/AssemblyInfo.vb new file mode 100644 index 00000000..1bbeb8b0 --- /dev/null +++ b/Windows/My Project/AssemblyInfo.vb @@ -0,0 +1,35 @@ +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' Allgemeine Informationen über eine Assembly werden über die folgenden +' Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +' die einer Assembly zugeordnet sind. + +' Werte der Assemblyattribute überprüfen + + + + + + + + + + +'Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird. + + +' Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +' +' Hauptversion +' Nebenversion +' Buildnummer +' Revision +' +' Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, +' übernehmen, indem Sie "*" eingeben: +' + + + diff --git a/Windows/My Project/Resources.Designer.vb b/Windows/My Project/Resources.Designer.vb new file mode 100644 index 00000000..2fde54bd --- /dev/null +++ b/Windows/My Project/Resources.Designer.vb @@ -0,0 +1,63 @@ +'------------------------------------------------------------------------------ +' +' Dieser Code wurde von einem Tool generiert. +' Laufzeitversion:4.0.30319.42000 +' +' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +' der Code erneut generiert wird. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + +Imports System + +Namespace My.Resources + + 'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + '-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + 'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + 'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + ''' + ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + ''' + _ + Friend Module Resources + + Private resourceMan As Global.System.Resources.ResourceManager + + Private resourceCulture As Global.System.Globalization.CultureInfo + + ''' + ''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + ''' + _ + 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("DigitalData.Modules.Windows.Resources", GetType(Resources).Assembly) + resourceMan = temp + End If + Return resourceMan + End Get + End Property + + ''' + ''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + ''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + ''' + _ + Friend Property Culture() As Global.System.Globalization.CultureInfo + Get + Return resourceCulture + End Get + Set + resourceCulture = value + End Set + End Property + End Module +End Namespace diff --git a/Windows/My Project/Resources.resx b/Windows/My Project/Resources.resx new file mode 100644 index 00000000..af7dbebb --- /dev/null +++ b/Windows/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/Windows/My Project/Settings.Designer.vb b/Windows/My Project/Settings.Designer.vb new file mode 100644 index 00000000..c458a722 --- /dev/null +++ b/Windows/My Project/Settings.Designer.vb @@ -0,0 +1,73 @@ +'------------------------------------------------------------------------------ +' +' Dieser Code wurde von einem Tool generiert. +' Laufzeitversion:4.0.30319.42000 +' +' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +' der Code erneut generiert wird. +' +'------------------------------------------------------------------------------ + +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 "Automatische My.Settings-Speicherfunktion" +#If _MyType = "WindowsForms" Then + Private Shared addedHandler As Boolean + + Private Shared addedHandlerLockObject As New Object + + _ + Private Shared Sub AutoSaveSettings(sender As Global.System.Object, 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.DigitalData.Modules.Windows.My.MySettings + Get + Return Global.DigitalData.Modules.Windows.My.MySettings.Default + End Get + End Property + End Module +End Namespace diff --git a/Windows/My Project/Settings.settings b/Windows/My Project/Settings.settings new file mode 100644 index 00000000..85b890b3 --- /dev/null +++ b/Windows/My Project/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Windows/NativeMethods.vb b/Windows/NativeMethods.vb new file mode 100644 index 00000000..80f17716 --- /dev/null +++ b/Windows/NativeMethods.vb @@ -0,0 +1,102 @@ +Imports System.Runtime.InteropServices +Imports System.Text + +Public Class NativeMethods + + Public Shared Function AttachThreadInput(ByVal idAttach As IntPtr, ByVal idAttachTo As IntPtr, fAttach As Boolean) As Boolean + End Function + + Public Shared Function GetFocus() As IntPtr + End Function + + Public Shared Function GetForegroundWindow() As IntPtr + End Function + + Public Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal WinTitle As String, ByVal MaxLength As Integer) As Integer + End Function + + Public Shared Function GetWindowTextLength(ByVal hwnd As Int32) As Integer + End Function + + Public Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, ByRef lpdwProcessID As Integer) As Integer + End Function + + Public Shared Function GetClassName(ByVal hwnd As Integer, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer + End Function + + Public Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As UInteger) As IntPtr + End Function + + Public Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UIntPtr, ByVal flAllocationType As UInteger, ByVal flProtect As PageProtection) As IntPtr + End Function + + Public Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef lpdwProcessId As UInteger) As UInteger + End Function + + Public Shared Function VirtualFreeEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UIntPtr, ByVal dwFreeType As UInteger) As Boolean + End Function + + Public Shared Function CloseHandle(ByVal hObject As IntPtr) As Boolean + End Function + + Public Shared Function MapViewOfFile(ByVal hFileMappingObject As IntPtr, ByVal dwDesiredAccess As UInteger, ByVal dwFileOffsetHigh As UInteger, ByVal dwFileOffsetLow As UInteger, ByVal dwNumberOfBytesToMap As UIntPtr) As IntPtr + End Function + + Public Shared Function UnmapViewOfFile(ByVal lpBaseAddress As IntPtr) As Boolean + End Function + + Public Shared Function CreateFileMapping(ByVal hFile As IntPtr, ByVal lpFileMappingAttributes As IntPtr, ByVal flProtect As PageProtection, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As IntPtr + End Function + + Public Shared Function SendMessage(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr + End Function + + Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, + ByVal lpBuffer As Byte(), ByVal nSize As UIntPtr, ByVal lpNumberOfBytesRead As IntPtr) As Boolean + End Function + + Public Shared Sub MoveMemoryFromByte(ByVal dest As IntPtr, ByRef src As Byte, ByVal size As Integer) + End Sub + + Public Shared Sub MoveMemoryToByte(ByRef dest As Byte, ByVal src As IntPtr, ByVal size As Integer) + End Sub + + Public Shared Function RegisterWindowMessage(ByVal lpString As String) As Integer + End Function + + Public Const STANDARD_RIGHTS_REQUIRED As Integer = &HF0000 + Public Const SECTION_QUERY As Short = &H1 + Public Const SECTION_MAP_WRITE As Short = &H2 + Public Const SECTION_MAP_READ As Short = &H4 + Public Const SECTION_MAP_EXECUTE As Short = &H8 + Public Const SECTION_EXTEND_SIZE As Short = &H10 + Public Const SECTION_ALL_ACCESS As Integer = STANDARD_RIGHTS_REQUIRED Or SECTION_QUERY Or SECTION_MAP_WRITE Or SECTION_MAP_READ Or SECTION_MAP_EXECUTE Or SECTION_EXTEND_SIZE + Public Const FILE_MAP_ALL_ACCESS As Integer = SECTION_ALL_ACCESS + Public Const PROCESS_VM_OPERATION As Short = &H8 + Public Const PROCESS_VM_READ As Short = &H10 + Public Const PROCESS_VM_WRITE As Short = &H20 + Public Const PROCESS_ALL_ACCESS As Long = &H1F0FFF + Public Const MEM_COMMIT As Short = &H1000 + Public Const MEM_RESERVE As Short = &H2000 + Public Const MEM_DECOMMIT As Short = &H4000 + Public Const MEM_RELEASE As Integer = &H8000 + Public Const MEM_FREE As Integer = &H10000 + Public Const MEM_PRIVATE As Integer = &H20000 + Public Const MEM_MAPPED As Integer = &H40000 + Public Const MEM_TOP_DOWN As Integer = &H100000 + Public Const INVALID_HANDLE_VALUE As Integer = -1 + + Public Enum PageProtection As UInteger + NoAccess = &H1 + [Readonly] = &H2 + ReadWrite = &H4 + WriteCopy = &H8 + Execute = &H10 + ExecuteRead = &H20 + ExecuteReadWrite = &H40 + ExecuteWriteCopy = &H80 + Guard = &H100 + NoCache = &H200 + WriteCombine = &H400 + End Enum +End Class diff --git a/Windows/Utils.vb b/Windows/Utils.vb new file mode 100644 index 00000000..c6c197c1 --- /dev/null +++ b/Windows/Utils.vb @@ -0,0 +1,96 @@ +Imports System.Text +Imports System.ComponentModel + +Public Class Utils + Private Shared GetControlNameMessage As Integer = 0 + + Public Shared Function GetWinFormsId(ByVal hWnd As IntPtr) As String + GetControlNameMessage = NativeMethods.RegisterWindowMessage("WM_GETCONTROLNAME") + Return XProcGetControlName(hWnd, GetControlNameMessage) + End Function + + Protected Shared Function XProcGetControlName(ByVal hwnd As IntPtr, ByVal msg As Integer) As String + Dim bytearray As Byte() = New Byte(65535) {} + Dim bufferMem As IntPtr = IntPtr.Zero + Dim written As IntPtr = IntPtr.Zero + Dim retHandle As IntPtr = IntPtr.Zero + Dim retVal As Boolean + Dim processHandle As IntPtr = IntPtr.Zero + Dim fileHandle As IntPtr = IntPtr.Zero + + If Not (Environment.OSVersion.Platform = PlatformID.Win32Windows) Then + + Try + Dim size As UInteger + size = 65536 + processHandle = NativeMethods.OpenProcess(NativeMethods.PROCESS_VM_OPERATION Or NativeMethods.PROCESS_VM_READ Or NativeMethods.PROCESS_VM_WRITE, False, GetProcessIdFromHWnd(hwnd)) + + If processHandle.ToInt64() = 0 Then + Throw New Win32Exception() + End If + + bufferMem = NativeMethods.VirtualAllocEx(processHandle, IntPtr.Zero, New UIntPtr(size), NativeMethods.MEM_RESERVE Or NativeMethods.MEM_COMMIT, NativeMethods.PageProtection.ReadWrite) + + If bufferMem.ToInt64() = 0 Then + Throw New Win32Exception() + End If + + retHandle = NativeMethods.SendMessage(hwnd, msg, New IntPtr(size), bufferMem) + retVal = NativeMethods.ReadProcessMemory(processHandle, bufferMem, bytearray, New UIntPtr(size), written) + + If Not retVal Then + Throw New Win32Exception() + End If + + Finally + retVal = NativeMethods.VirtualFreeEx(processHandle, bufferMem, New UIntPtr(0), NativeMethods.MEM_RELEASE) + + If Not retVal Then + Throw New Win32Exception() + End If + + NativeMethods.CloseHandle(processHandle) + End Try + Else + + Try + Dim size2 As Integer + size2 = 65536 + fileHandle = NativeMethods.CreateFileMapping(New IntPtr(NativeMethods.INVALID_HANDLE_VALUE), IntPtr.Zero, NativeMethods.PageProtection.ReadWrite, 0, size2, Nothing) + + If fileHandle.ToInt64() = 0 Then + Throw New Win32Exception() + End If + + bufferMem = NativeMethods.MapViewOfFile(fileHandle, NativeMethods.FILE_MAP_ALL_ACCESS, 0, 0, New UIntPtr(0)) + + If bufferMem.ToInt64() = 0 Then + Throw New Win32Exception() + End If + + NativeMethods.MoveMemoryFromByte(bufferMem, bytearray(0), size2) + retHandle = NativeMethods.SendMessage(hwnd, msg, New IntPtr(size2), bufferMem) + NativeMethods.MoveMemoryToByte(bytearray(0), bufferMem, 1024) + Finally + NativeMethods.UnmapViewOfFile(bufferMem) + NativeMethods.CloseHandle(fileHandle) + End Try + End If + + Return ByteArrayToString(bytearray) + End Function + + Private Shared Function GetProcessIdFromHWnd(ByVal hwnd As IntPtr) As UInteger + Dim pid As UInteger + NativeMethods.GetWindowThreadProcessId(hwnd, pid) + Return pid + End Function + + Private Shared Function ByteArrayToString(ByVal bytes As Byte()) As String + If Environment.OSVersion.Platform = PlatformID.Win32Windows Then + Return Encoding.[Default].GetString(bytes).TrimEnd(vbNullChar) + Else + Return Encoding.Unicode.GetString(bytes).TrimEnd(vbNullChar) + End If + End Function +End Class diff --git a/Windows/Window.vb b/Windows/Window.vb new file mode 100644 index 00000000..270c6f03 --- /dev/null +++ b/Windows/Window.vb @@ -0,0 +1,121 @@ +Imports System.Text +Imports DigitalData.Modules.Logging + +Public Class Window + Private _Logger As Logger + + Public Class WindowInfo + Public WindowTitle As String = "" + Public ProcessName As String = "" + Public ClassName As String = "" + Public ProcessId As Integer = 0 + Public ControlName As String = "" + Public hWnd As IntPtr + End Class + + Public Sub New(LogConfig As LogConfig) + _Logger = LogConfig.getLogger() + End Sub + + ''' + ''' Returns Information about the currently focused window + ''' + Public Function GetWindowInfo() As WindowInfo + Dim hWnd As IntPtr = NativeMethods.GetForegroundWindow() + If hWnd = IntPtr.Zero Then + Return Nothing + End If + + Return GetWindowInfo(hWnd) + End Function + + ''' + ''' Returns Information about the Window with `hWnd` + ''' + Public Function GetWindowInfo(ByVal hWnd As IntPtr) As WindowInfo + Dim oPID As Integer = 0 + Dim oTitleLength As Int32 = NativeMethods.GetWindowTextLength(hWnd) + Dim oWindowTitle As String = StrDup(oTitleLength + 1, "*") + Dim oClassBuilder As New StringBuilder(64) + + NativeMethods.GetWindowText(hWnd, oWindowTitle, oTitleLength + 1) + NativeMethods.GetWindowThreadProcessId(hWnd, oPID) + + If oPID = 0 Then + Return Nothing + End If + + Dim oProcess As Process = Process.GetProcessById(oPID) + + If oProcess Is Nothing Then + Return Nothing + End If + + NativeMethods.GetClassName(hWnd, oClassBuilder, 64) + + Return New WindowInfo With { + .hWnd = hWnd, + .ClassName = oClassBuilder.ToString, + .ProcessId = oProcess.Id, + .ProcessName = oProcess.ProcessName, + .WindowTitle = oWindowTitle.Replace(vbNullChar, String.Empty) + } + End Function + + Public Function FocusedControlinActiveWindow(WindowHandle As IntPtr) As IntPtr + Try + Dim oActiveWindowHandle As IntPtr = NativeMethods.GetForegroundWindow + Dim oActiveWindowThread As IntPtr = NativeMethods.GetWindowThreadProcessId(oActiveWindowHandle, 0) + Dim oThisWindowThread As IntPtr = NativeMethods.GetWindowThreadProcessId(WindowHandle, 0) + NativeMethods.AttachThreadInput(oActiveWindowThread, oThisWindowThread, True) + Dim oFocusedControlHandle As IntPtr = NativeMethods.GetFocus() + NativeMethods.AttachThreadInput(oActiveWindowThread, oThisWindowThread, False) + Return oFocusedControlHandle + Catch ex As Exception + Return Nothing + End Try + End Function + + ''' + ''' Returns the currently focused control + ''' + ''' Current window handle; can be obtained from Me.Handle + Public Function GetFocusedControl(WindowHandle As IntPtr) As WindowInfo + Try + Dim oWindow = GetWindowInfo() + + If oWindow Is Nothing Then + Return Nothing + End If + + Dim oThreadId As IntPtr = NativeMethods.GetWindowThreadProcessId(oWindow.hWnd, 0) + Dim oMyThreadId As IntPtr = NativeMethods.GetWindowThreadProcessId(WindowHandle, 0) + + If NativeMethods.AttachThreadInput(oThreadId, oMyThreadId, True) Then + Try + Dim oControlhWnd = NativeMethods.GetFocus() + Dim oControl As WindowInfo = GetWindowInfo(oControlhWnd) + + If oControl Is Nothing Then + Return Nothing + End If + + Dim oName = Utils.GetWinFormsId(oControlhWnd) + oControl.ControlName = oName + + Return oControl + Catch ex As Exception + _Logger.Error(ex) + Finally + NativeMethods.AttachThreadInput(oThreadId, oMyThreadId, False) + End Try + End If + + Return Nothing + Catch ex As Exception + _Logger.Error(ex) + Return Nothing + End Try + + End Function +End Class diff --git a/Windows/Windows.vbproj b/Windows/Windows.vbproj new file mode 100644 index 00000000..6a07b179 --- /dev/null +++ b/Windows/Windows.vbproj @@ -0,0 +1,121 @@ + + + + + Debug + AnyCPU + {5EFAEF9B-90B9-4F05-9F70-F79AD77FFF86} + Library + DigitalData.Modules.Windows + DigitalData.Modules.Windows + 512 + Windows + v4.6.1 + + + true + full + true + true + bin\Debug\ + DigitalData.Modules.Windows.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + pdbonly + false + true + true + bin\Release\ + DigitalData.Modules.Windows.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + On + + + Binary + + + Off + + + On + + + + + ..\packages\NLog.4.6.7\lib\net45\NLog.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + Application.myapp + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + Designer + + + + + MyApplicationCodeGenerator + Application.Designer.vb + + + SettingsSingleFileGenerator + My + Settings.Designer.vb + + + + + + {903B2D7D-3B80-4BE9-8713-7447B704E1B0} + Logging + + + + \ No newline at end of file diff --git a/Windows/packages.config b/Windows/packages.config new file mode 100644 index 00000000..99e34262 --- /dev/null +++ b/Windows/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ZooFlow/ApplicationEvents.vb b/ZooFlow/ApplicationEvents.vb index cce43f6a..7465a313 100644 --- a/ZooFlow/ApplicationEvents.vb +++ b/ZooFlow/ApplicationEvents.vb @@ -19,6 +19,7 @@ Namespace My Public Sub App_Startup() Handles Me.Startup Dim oLogConfig As New LogConfig(PathType.AppData) + oLogConfig.Debug = True ' System Config files like Service Url will be saved in %LocalAppdata% so they will remain on the machine Dim oSystemConfigManager As New ConfigManager(Of ClassConfig)(oLogConfig, diff --git a/ZooFlow/ClassInit.vb b/ZooFlow/ClassInit.vb index dffc0732..67152402 100644 --- a/ZooFlow/ClassInit.vb +++ b/ZooFlow/ClassInit.vb @@ -6,6 +6,7 @@ Imports DigitalData.Modules.Language.Utils Imports DigitalData.Modules.Logging Imports ZooFlow.ClassInitLoader Imports ZooFlow.ClassConstants +Imports ZooFlow.State Public Class ClassInit Private _MainForm As frmMain @@ -45,6 +46,7 @@ Public Class ClassInit oInit.Run() End If End Sub + Private Function SetupDatabase() As Boolean If My.SystemConfig.ConnectionString = String.Empty Then Dim oResult = frmConfigDatabase.ShowDialog() @@ -67,15 +69,15 @@ Public Class ClassInit If Not IsNothing(e.Error) Then MsgBox("Beim Initialisieren des Programms ist folgender Fehler aufgetreten:" & vbNewLine & vbNewLine & e.Error.Message, MsgBoxStyle.Critical, _MainForm.Text) Application.ExitThread() - End If - - ' Copy back state from MyApplication Helper to My.Application - Dim oMyApplication As My.MyApplication = DirectCast(e.Result, My.MyApplication) - My.Application.User = oMyApplication.User - My.Application.Modules = oMyApplication.Modules - My.Application.ModulesActive = oMyApplication.ModulesActive + Else + ' Copy back state from MyApplication Helper to My.Application + Dim oMyApplication As My.MyApplication = DirectCast(e.Result, My.MyApplication) + My.Application.User = oMyApplication.User + My.Application.Modules = oMyApplication.Modules + My.Application.ModulesActive = oMyApplication.ModulesActive - RaiseEvent Completed(sender, Nothing) + RaiseEvent Completed(sender, Nothing) + End If End Sub Private Sub CheckConnectivity(MyApplication As My.MyApplication) @@ -94,7 +96,7 @@ Public Class ClassInit Private Sub InitializeUser(MyApplication As My.MyApplication) Try - Dim oSql As String = My.Common.Queries.FNDD_MODULE_INIT(MyApplication.User.UserName) + Dim oSql As String = My.Queries.Common.FNDD_MODULE_INIT(Environment.UserName) Dim oDatatable As DataTable = My.Database.GetDatatable(oSql) If oDatatable.Rows.Count <= 1 Then @@ -148,7 +150,7 @@ Public Class ClassInit Dim oName As String = Row.Item("NAME").ToString If Not MyApplication.Modules.ContainsKey(ModuleName) Then - MyApplication.Modules.Item(ModuleName) = New ClassModuleState() + MyApplication.Modules.Item(ModuleName) = New DigitalData.Modules.ZooFlow.State.ModuleState() End If Select Case oName diff --git a/ZooFlow/ClassProfileFilter.vb b/ZooFlow/ClassProfileFilter.vb new file mode 100644 index 00000000..37d75905 --- /dev/null +++ b/ZooFlow/ClassProfileFilter.vb @@ -0,0 +1,495 @@ +Imports System.Text.RegularExpressions +Imports DigitalData.Modules.Language.Utils +Imports DigitalData.Modules.Logging +Imports DigitalData.Modules.Windows +Imports DigitalData.Modules.ZooFlow.Params + +Public Class ClassProfileFilter + Private _ProfileTable As DataTable + Private _ProcessTable As DataTable + Private _WindowTable As DataTable + Private _ControlTable As DataTable + Private _Profiles As List(Of ProfileData) + Private _DebugData As DebugData + Private _Logger As Logger + Private _Window As Window + + Private _TreeView As New TreeView + + ' TODO: Fill this Class!!!! :D + Class DebugData + Public ProcessMatch As List(Of String) + Public ClipboardMatch As List(Of String) + Public WindowMatch As List(Of String) + Public WindowRegexMatch As List(Of String) + End Class + + Public ReadOnly Property Profiles As List(Of ProfileData) + Get + Return _Profiles + End Get + End Property + + Public ReadOnly Property DebugTree As TreeView + Get + Return _TreeView + End Get + End Property + + + Public Sub New(LogConfig As LogConfig, ProfileDatatable As DataTable, ProcessTable As DataTable, WindowDatatable As DataTable, ControlDatatable As DataTable) + Try + _Logger = LogConfig.GetLogger() + _DebugData = New DebugData() + _ProfileTable = ProfileDatatable + _ProcessTable = ProcessTable + _WindowTable = WindowDatatable + _ControlTable = ControlDatatable + _Profiles = TransformProfiles() + _Window = New Window(LogConfig) + Catch ex As Exception + _Logger.Error(ex) + Throw ex + End Try + End Sub + + Public Function ToList() As List(Of ProfileData) + Return _Profiles + End Function + + Private Function FindNode(ByVal Node As TreeNode, SearchTerm As String) + Dim oNode As TreeNode + For Each oNode In Node.Nodes + If oNode.Text = SearchTerm Then + Return oNode + End If + Next + Return Node + End Function + + Private Function GetLowestNode(ByVal Node As TreeNode) As TreeNode + If Node.GetNodeCount(False) = 1 Then + Return GetLowestNode(Node.Nodes.Item(0)) + Else + Return Node + End If + End Function + + Public Function FilterProfilesByClipboardRegex(Profiles As List(Of ProfileData), ClipboardContents As String) As List(Of ProfileData) + Dim oFilteredProfiles As New List(Of ProfileData) + For Each oProfile In Profiles + _Logger.Debug("Current Profile: {0}", oProfile.Name) + + Try + Dim oRegex As New Regex(oProfile.Regex) + Dim oMatch = oRegex.Match(ClipboardContents) + If oMatch.Success Then + _Logger.Debug("FilterProfilesByClipboardRegex: Clipboard Regex Matched: {0}", ClipboardContents) + 'TODO: Add Debug Data + oFilteredProfiles.Add(oProfile) + oProfile.IsMatched = True + Dim oNode As New TreeNode($"Profile: {oProfile.Name}") + oNode.ImageIndex = 0 + Dim f = New Font("Tahoma", 9, FontStyle.Bold) + oNode.NodeFont = f + _TreeView.Nodes.Add(oNode) + Dim oSubnode As New TreeNode($"MATCH on Global Clipboard Regex: {oProfile.Regex}") + oSubnode.ImageIndex = 1 + oSubnode.Tag = oProfile.Name & "-REGEX" + oNode.Nodes.Add(oSubnode) + End If + Catch ex As Exception + _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oProfile.Regex, ClipboardContents) + _Logger.Error(ex) + End Try + Next + + Return oFilteredProfiles + End Function + Public Function FilterProfilesByProcess(Profiles As List(Of ProfileData), CurrentProcessName As String) As List(Of ProfileData) + Dim oFilteredProfiles As New List(Of ProfileData) + Try + For Each oProfile In Profiles + Dim oGuid = oProfile.Guid + + If oProfile.IsMatched = False Then + Continue For + End If + + + Dim oProcesses As New List(Of ProfileData.ProcessData) + For Each oProcessDef As ProfileData.ProcessData In oProfile.Processes + If oProcessDef.ProfileId <> oGuid Then + Continue For + End If + _Logger.Debug($"FilterProfilesByProcess: Checking Profile: {oProfile.Name} ...") + If oProcessDef.ProcessName.ToLower = CurrentProcessName.ToLower Then + _Logger.Debug($"Yes...Processname Matched: {oProcessDef.ProcessName}") + 'oProfile.MATCH_PROCESSNAME = $"Processname Matched: {oProfile.ProcessName}" + 'TODO: Add Debug Data + oFilteredProfiles.Add(oProfile) + oProfile.MatchedProcessID = oProcessDef.Guid + oProcessDef.IsMatched = True + oProcesses.Add(oProcessDef) + oProfile.IsMatched = True + oProfile.MatchedProcessID = oProcessDef.Guid + Dim oParentNode As TreeNode + Dim oExit = False + For Each oTreeNode As TreeNode In _TreeView.Nodes + For Each oNodes As TreeNode In oTreeNode.Nodes + If oExit = True Then Exit For + If oNodes.Tag = oProfile.Name & "-REGEX" Then + oParentNode = oNodes + oExit = True + Exit For + End If + Next + Next + + If Not IsNothing(oParentNode) Then + Dim oNode As New TreeNode($"MATCH on Process: {oProcessDef.ProcessName}") + oNode.ImageIndex = 4 + oNode.Tag = oProfile.Name & "-PROCESS" + oParentNode.Nodes.Add(oNode) + End If + End If + Next + If oFilteredProfiles.Count > 0 Then + oProfile.Processes = oProcesses + End If + Next + + Return oFilteredProfiles + Catch ex As Exception + _Logger.Warn("Unexpected error in FilterProfilesByProcess...") + _Logger.Error(ex) + End Try + + End Function + Public Function FilterWindowsByWindowTitleRegex(Profiles As List(Of ProfileData), WindowTitle As String) As List(Of ProfileData) + Dim oProfiles As New List(Of ProfileData) + + For Each oProfile As ProfileData In Profiles + _Logger.Debug("Checking WindowDefinition for profile: {0}...", oProfile.Name) + If oProfile.IsMatched = False Then Continue For + Dim oWindows As New List(Of ProfileData.WindowData) + + For Each oWindowDef As ProfileData.WindowData In oProfile.Windows + If oWindowDef.WindowProcessID <> oProfile.MatchedProcessID Then Continue For + Try + If oWindowDef.Regex = String.Empty Then + oProfile.MatchedWindowID = oWindowDef.Guid + oWindowDef.IsMatched = True + oWindows.Add(oWindowDef) + Exit For + End If + + Dim oRegex As New Regex(oWindowDef.Regex) + Dim oMatch = oRegex.Match(WindowTitle) + + If oMatch.Success Then + _Logger.Debug("MATCH on WindowTitle: {0}", WindowTitle) + 'TODO: Add Debug Data + oProfile.MatchedWindowID = oWindowDef.Guid + oWindowDef.IsMatched = True + oWindows.Add(oWindowDef) + Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfile.Name & "-REGEX") + If Not IsNothing(olowestNode) Then + Dim oNode As New TreeNode($"MATCH on WindowTitle: [{WindowTitle}]") + oNode.ImageIndex = 3 + oNode.Tag = oProfile.Name & "-WINDOW" + olowestNode.Nodes.Add(oNode) + End If + Exit For + End If + Catch ex As Exception + _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oWindowDef.Regex, WindowTitle) + _Logger.Error(ex) + End Try + Next + + If oWindows.Count > 0 Then + oProfile.Windows = oWindows + oProfile.IsMatched = True + oProfiles.Add(oProfile) + End If + Next + + Return oProfiles + End Function + + Public Function FilterWindowsByWindowClipboardRegex(Profiles As List(Of ProfileData), ClipboardContents As String) As List(Of ProfileData) + Dim oProfiles As New List(Of ProfileData) + + For Each oProfile As ProfileData In Profiles + _Logger.Debug("Current Profile: {0}", oProfile.Name) + + Dim oWindows As New List(Of ProfileData.WindowData) + + For Each w As ProfileData.WindowData In oProfile.Windows + Try + If w.Regex = String.Empty Then + oWindows.Add(w) + End If + + Dim oRegex As New Regex(w.Regex) + Dim oMatch = oRegex.Match(ClipboardContents) + + If oMatch.Success Then + _Logger.Debug("Window Clipboard Regex Matched: {0}", ClipboardContents) + Dim oResult As TreeNode + For Each oTreeNode In _TreeView.Nodes + If Not IsNothing(oResult) Then Exit For + If oTreeNode.Tag = oProfile.Name & "-REGEX" Then + oResult = oTreeNode + End If + + + Next + If Not IsNothing(oResult) Then + Dim oNode As New TreeNode($"MATCH on WINDOW Clipboard Regex: [{w.Regex}]") + oNode.ImageIndex = 2 + oNode.Tag = oProfile.Name & "-WINDOW_REGEX" + Dim olowestNode As TreeNode = GetLowestNode(oResult) + olowestNode.Nodes.Add(oNode) + End If + + oWindows.Add(w) + + + End If + Catch ex As Exception + _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", w.Regex, ClipboardContents) + _Logger.Error(ex) + End Try + Next + + If oWindows.Count > 0 Then + oProfile.Windows = oWindows + oProfiles.Add(oProfile) + End If + Next + + Return oProfiles + End Function + + Public Function FilterProfilesByFocusedControl(Profiles As List(Of ProfileData), ClipboardContents As String, ControlFocusresult As String) As List(Of ProfileData) + Dim oWindow As Window.WindowInfo + Dim oFocusedControl As Window.WindowInfo + Dim oFocusedControlName As String = String.Empty + + Try + oWindow = _Window.GetWindowInfo() + oFocusedControl = _Window.GetFocusedControl(oWindow.hWnd) + + If oFocusedControl Is Nothing Then + _Logger.Info("Could not get FocusedControl in Window (Old method) {0}", oWindow.WindowTitle) + oFocusedControlName = String.Empty + Else + oFocusedControlName = oFocusedControl.ControlName + End If + Catch ex As Exception + _Logger.Warn("Error while getting Focused control (Old method)") + _Logger.Error(ex) + oFocusedControlName = String.Empty + End Try + + Dim oFilteredProfiles As New List(Of ProfileData) + + For Each oProfileMatchedSofar In Profiles + If oProfileMatchedSofar.IsMatched = False Then Continue For + + _Logger.Debug("Checking ControlDefiniotion on profile: {0}", oProfileMatchedSofar.Name) + If oProfileMatchedSofar.Controls.Count = 0 Then + oFilteredProfiles.Add(oProfileMatchedSofar) + + Dim oNode As New TreeNode($"No Controls configured!") + oNode.ImageIndex = 2 + oNode.ForeColor = Color.Blue + oNode.Tag = oProfileMatchedSofar.Name & "-NOCONTROLCONFIG" + Dim f = New Font("Tahoma", 10, FontStyle.Bold) + oNode.NodeFont = f + _TreeView.Nodes.Add(oNode) + Continue For + End If + + Dim oControls As New List(Of ProfileData.ControlData) + + For Each oControlDefinition In oProfileMatchedSofar.Controls + Try + If oControlDefinition.WindowId <> oProfileMatchedSofar.MatchedWindowID Then Continue For + _Logger.Debug($"Working on ControlDefinition: {oControlDefinition.Guid}-{oControlDefinition.ControlName}...") + If oControlDefinition.Regex = String.Empty Then + oProfileMatchedSofar.MatchedControlID = oControlDefinition.Guid + oControlDefinition.IsMatched = True + oControls.Add(oControlDefinition) + Exit For + End If + 'Dim oResult As TreeNode + 'For Each oTreeNode In CurrMatchTreeView.Nodes + ' oResult = NodeFind(oTreeNode, $"Global Clipboard Regex Matched [{oProfile.Regex}]") + 'Next + 'Dim oNode As TreeNode + Dim oNodeCaption As String + 'Dim oAddNode As Boolean = False + Dim oRegex As New Regex(oControlDefinition.Regex) + + Dim oFocusedControlResult As String = "" + + If oControlDefinition.AutomationId <> String.Empty And oControlDefinition.ControlName = String.Empty Then + _Logger.Debug($"AutomationID should be used...") + If Not IsNothing(ControlFocusresult) Then + If ControlFocusresult <> String.Empty Then + _Logger.Debug($"AutomationID will be used...") + oFocusedControlResult = ControlFocusresult + End If + End If + ElseIf oControlDefinition.AutomationId = String.Empty And oControlDefinition.ControlName <> String.Empty Then + _Logger.Debug($"ControlName should be used...") + If Not IsNothing(oFocusedControlName) Then + If oFocusedControlName <> String.Empty Then + _Logger.Debug($"ControlName will be used...") + oFocusedControlResult = oFocusedControlName + End If + End If + + End If + If oFocusedControlResult <> String.Empty Then + Dim oControlRegex As New Regex(oControlDefinition.Regex) + Dim oControlMatch = oRegex.Match(oFocusedControlResult) + + If oControlMatch.Success Then + _Logger.Debug($"MATCH on Focused Control [{oFocusedControlResult}] with Regex [{oControlDefinition.Regex}]") + oProfileMatchedSofar.IsMatched = True + oProfileMatchedSofar.MatchedControlID = oControlDefinition.Guid + oControlDefinition.IsMatched = True + oControls.Add(oControlDefinition) + Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfileMatchedSofar.Name & "-REGEX") + If Not IsNothing(olowestNode) Then + Dim oNode As New TreeNode($"MATCH on Focused Control [{oFocusedControlResult}] with Regex [{oControlDefinition.Regex}]") + oNode.ImageIndex = 2 + oNode.Tag = oProfileMatchedSofar.Name & "-CONTROL" + olowestNode.Nodes.Add(oNode) + End If + Exit For + End If + End If + Catch ex As Exception + _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oControlDefinition.Regex, oFocusedControlName) + _Logger.Error(ex) + End Try + Next + + If oControls.Count > 0 Then + oProfileMatchedSofar.Controls = oControls + oFilteredProfiles.Add(oProfileMatchedSofar) + Else + Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfileMatchedSofar.Name & "-REGEX") + If Not IsNothing(olowestNode) Then + Dim oNode As New TreeNode($"NO MATCHES on Focused Control, Please check the Config") + oNode.ImageIndex = 2 + oNode.Tag = oProfileMatchedSofar.Name & "-CONTROLNoMatch" + olowestNode.Nodes.Add(oNode) + End If + End If + Next + + Return oFilteredProfiles + End Function + Private Function Node_Get_Lowest_Node(NodeTag As String) As TreeNode + Dim oExit = False + Dim oParentNode As TreeNode + For Each oTreeNode As TreeNode In _TreeView.Nodes + For Each oNodes As TreeNode In oTreeNode.Nodes + If oExit = True Then Exit For + If oNodes.Tag = NodeTag Then + oParentNode = oNodes + oExit = True + Exit For + End If + Next + Next + Dim olowestNode As TreeNode = GetLowestNode(oParentNode) + + Return olowestNode + End Function + Public Function ClearNotMatchedProfiles(Profiles As List(Of ProfileData)) As List(Of ProfileData) + Dim oFilteredProfiles As New List(Of ProfileData) + For Each oProfile In Profiles + If oProfile.IsMatched Then + oFilteredProfiles.Add(oProfile) + End If + Next + Return oFilteredProfiles + End Function + Private Function TransformProfiles() As List(Of ProfileData) + Dim oList As New List(Of ProfileData) + + For Each oRow As DataRow In _ProfileTable.Rows + Dim oProfileId = oRow.Item("GUID") + Dim oProcessList As List(Of ProfileData.ProcessData) = TransformProcesses(oProfileId, _ProcessTable) + Dim oWindowList As List(Of ProfileData.WindowData) = TransformWindows(oProfileId, _WindowTable) + Dim oControlList As List(Of ProfileData.ControlData) = TransformControls(oProfileId, _ControlTable) + + oList.Add(New ProfileData() With { + .Guid = oRow.Item("GUID"), + .Regex = NotNull(oRow.Item("REGEX_EXPRESSION"), String.Empty), + .Name = NotNull(oRow.Item("NAME"), String.Empty), + .Comment = NotNull(oRow.Item("COMMENT"), String.Empty), + .ProfileType = NotNull(oRow.Item("PROFILE_TYPE"), String.Empty), + .Processes = oProcessList, + .Windows = oWindowList, + .Controls = oControlList + }) + Next + + Return oList + End Function + + Private Function TransformControls(ProfileId As Integer, ControlDatatable As DataTable) As List(Of ProfileData.ControlData) + Dim oControlList As New List(Of ProfileData.ControlData) + + For Each oRow As DataRow In ControlDatatable.Rows + If oRow.Item("PROFILE_ID") = ProfileId Then + oControlList.Add(New ProfileData.ControlData() With { + .Guid = oRow.Item("GUID"), + .Description = NotNull(oRow.Item("DESCRIPTION"), String.Empty), + .Regex = NotNull(oRow.Item("REGEX"), String.Empty), + .AutomationId = NotNull(oRow.Item("AUTOMATION_ID"), String.Empty), + .WindowId = oRow.Item("WINDOW_ID") + }) + End If + Next + + Return oControlList + End Function + Private Function TransformProcesses(ProfileId As Integer, ProcessDatatable As DataTable) As List(Of ProfileData.ProcessData) + Dim oProcessList As New List(Of ProfileData.ProcessData) + + For Each oRow As DataRow In ProcessDatatable.Rows + oProcessList.Add(New ProfileData.ProcessData() With { + .Guid = oRow.Item("GUID"), + .ProfileId = oRow.Item("PROFILE_ID"), + .ProcessName = NotNull(oRow.Item("PROC_NAME"), String.Empty) + }) + + Next + + Return oProcessList + End Function + Private Function TransformWindows(ProfileId As Integer, WindowDatatable As DataTable) As List(Of ProfileData.WindowData) + Dim oWindowList As New List(Of ProfileData.WindowData) + + For Each oRow As DataRow In WindowDatatable.Rows + oWindowList.Add(New ProfileData.WindowData() With { + .Guid = oRow.Item("GUID"), + .WindowProcessID = oRow.Item("PROCESS_ID"), + .Title = NotNull(oRow.Item("DESCRIPTION"), String.Empty), + .Regex = NotNull(oRow.Item("REGEX"), String.Empty), + .Sequence = NotNull(oRow.Item("SEQUENCE"), 0) + }) + Next + + Return oWindowList + End Function +End Class diff --git a/ZooFlow/ClipboardWatcher/State.vb b/ZooFlow/ClipboardWatcher/State.vb new file mode 100644 index 00000000..795b4ab1 --- /dev/null +++ b/ZooFlow/ClipboardWatcher/State.vb @@ -0,0 +1,8 @@ +Namespace ClipboardWatcher + Public Class State + Public UserProfiles As DataTable + Public ProfileProcesses As DataTable + Public ProfileWindows As DataTable + Public ProfileControls As DataTable + End Class +End Namespace \ No newline at end of file diff --git a/ZooFlow/Common/ClassCommon.vb b/ZooFlow/Common/ClassCommon.vb deleted file mode 100644 index 8c9fc458..00000000 --- a/ZooFlow/Common/ClassCommon.vb +++ /dev/null @@ -1,3 +0,0 @@ -Public Class ClassCommon - Public Property Queries As New ClassCommonQueries -End Class diff --git a/ZooFlow/My Project/DataSources/ZooFlow.State.ClassUserState.datasource b/ZooFlow/My Project/DataSources/ZooFlow.State.ClassUserState.datasource new file mode 100644 index 00000000..61748e7a --- /dev/null +++ b/ZooFlow/My Project/DataSources/ZooFlow.State.ClassUserState.datasource @@ -0,0 +1,10 @@ + + + + ZooFlow.State.ClassUserState, ZooFlow, Version=0.0.1.0, Culture=neutral, PublicKeyToken=null + \ No newline at end of file diff --git a/ZooFlow/My Project/licenses.licx b/ZooFlow/My Project/licenses.licx index 4ba5c3e6..febe7ed9 100644 --- a/ZooFlow/My Project/licenses.licx +++ b/ZooFlow/My Project/licenses.licx @@ -1,8 +1,9 @@ -DevExpress.XtraEditors.PictureEdit, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a -DevExpress.XtraBars.Ribbon.RibbonControl, DevExpress.XtraBars.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a -DevExpress.XtraLayout.LayoutControl, DevExpress.XtraLayout.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a -DevExpress.XtraEditors.ComboBoxEdit, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a DevExpress.XtraEditors.TextEdit, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a +DevExpress.XtraEditors.ButtonEdit, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a +DevExpress.XtraEditors.ComboBoxEdit, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a DevExpress.XtraEditors.ProgressBarControl, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a +DevExpress.XtraLayout.LayoutControl, DevExpress.XtraLayout.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a DevExpress.XtraEditors.CheckEdit, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a -DevExpress.XtraEditors.ButtonEdit, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a +DevExpress.XtraBars.Ribbon.RibbonControl, DevExpress.XtraBars.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a +DevExpress.XtraEditors.PictureEdit, DevExpress.XtraEditors.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a +DevExpress.XtraGrid.GridControl, DevExpress.XtraGrid.v18.1, Version=18.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a diff --git a/ZooFlow/MyApplication.vb b/ZooFlow/MyApplication.vb index 7d1362cb..3c08f6ae 100644 --- a/ZooFlow/MyApplication.vb +++ b/ZooFlow/MyApplication.vb @@ -1,6 +1,8 @@ Imports DigitalData.Modules.Config Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Database +Imports DigitalData.Modules.ZooFlow +Imports ZooFlow.State Namespace My ''' @@ -26,21 +28,19 @@ Namespace My Property LogConfig As LogConfig Property MainForm As frmMain Property Database As MSSQLServer - - Property Common As New ClassCommon + Property Queries As New ClassQueries End Module ''' ''' Extends the My.Application Namespace to hold Application State ''' Example: My.Application.User ''' - Partial Class MyApplication - ' User Config - Public User As New ClassUserState() - Public Service As New ClassServiceState() - Public Modules As New Dictionary(Of String, ClassModuleState) - Public ModulesActive As New List(Of String) + Partial Friend Class MyApplication + Public Property User As New State.UserState + Public Property Service As New State.ServiceState + Public Property Modules As New Dictionary(Of String, State.ModuleState) + Public Property ModulesActive As New List(Of String) + Public Property ClipboardWatcher As New ClipboardWatcher.State End Class End Namespace - diff --git a/ZooFlow/Queries/ClassClipboardWatcherQueries.vb b/ZooFlow/Queries/ClassClipboardWatcherQueries.vb new file mode 100644 index 00000000..9148f6b9 --- /dev/null +++ b/ZooFlow/Queries/ClassClipboardWatcherQueries.vb @@ -0,0 +1,17 @@ +Public Class ClassClipboardWatcherQueries + Public Function VWCW_USER_PROFILE(UserId As Integer) As String + Return $"SELECT DISTINCT GUID, NAME, REGEX_EXPRESSION, COMMENT, PROC_NAME, PROFILE_TYPE FROM VWCW_USER_PROFILE WHERE USER_ID = {UserId} OR GROUP_ID IN (SELECT DISTINCT GUID FROM TBDD_GROUPS WHERE GUID IN (SELECT GROUP_ID FROM TBDD_GROUPS_USER WHERE USER_ID = {0}))" + End Function + + Public Function TBCW_PROFILE_PROCESS(UserId As Integer) As String + Return $"SELECT T.* FROM TBCW_PROFILE_PROCESS T, VWCW_USER_PROFILE T1 WHERE T.PROFILE_ID = T1.GUID AND T1.USER_ID = {UserId}" + End Function + + Public Function VWCW_PROFILE_REL_WINDOW(UserId As Integer) As String + Return $"SELECT * FROM VWCW_PROFILE_REL_WINDOW WHERE USER_ID = {UserId}" + End Function + + Public Function VWCW_PROFILE_REL_CONTROL(UserId As Integer) As String + Return $"SELECT * FROM VWCW_PROFILE_REL_CONTROL WHERE USER_ID = {UserId}" + End Function +End Class diff --git a/ZooFlow/Common/ClassCommonQueries.vb b/ZooFlow/Queries/ClassCommonQueries.vb similarity index 100% rename from ZooFlow/Common/ClassCommonQueries.vb rename to ZooFlow/Queries/ClassCommonQueries.vb diff --git a/ZooFlow/Queries/ClassQueries.vb b/ZooFlow/Queries/ClassQueries.vb new file mode 100644 index 00000000..03249573 --- /dev/null +++ b/ZooFlow/Queries/ClassQueries.vb @@ -0,0 +1,4 @@ +Public Class ClassQueries + Public Property Common As New ClassCommonQueries + Public Property ClipboardWatcher As New ClassClipboardWatcherQueries +End Class diff --git a/ZooFlow/State/ClassModuleState.vb b/ZooFlow/State/ClassModuleState.vb deleted file mode 100644 index f3cc51e9..00000000 --- a/ZooFlow/State/ClassModuleState.vb +++ /dev/null @@ -1,5 +0,0 @@ -Public Class ClassModuleState - Public HasAccess As Boolean - Public IsAdmin As Boolean - Public LoggedIn As Integer -End Class \ No newline at end of file diff --git a/ZooFlow/State/ClassServiceState.vb b/ZooFlow/State/ClassServiceState.vb deleted file mode 100644 index 25047b48..00000000 --- a/ZooFlow/State/ClassServiceState.vb +++ /dev/null @@ -1,4 +0,0 @@ -Public Class ClassServiceState - Public Property Online As Boolean = True - Public Property LastChecked As DateTime = DateTime.Now -End Class diff --git a/ZooFlow/State/ClassUserState.vb b/ZooFlow/State/ClassUserState.vb deleted file mode 100644 index 87a03133..00000000 --- a/ZooFlow/State/ClassUserState.vb +++ /dev/null @@ -1,25 +0,0 @@ -Imports System.Threading - -''' -''' Helper Class to hold User State -''' -Public Class ClassUserState - Public UserId As Integer - Public UserName As String - Public Surname As String - Public GivenName As String - Public ShortName As String - Public Email As String - Public MachineName As String - Public DateFormat As String - Public Language As String - - ''' - ''' Initialize user object with values that can be read from the environment - ''' - Public Sub New() - Language = Thread.CurrentThread.CurrentCulture.Name - UserName = Environment.UserName - MachineName = Environment.MachineName - End Sub -End Class \ No newline at end of file diff --git a/ZooFlow/ZooFlow.vbproj b/ZooFlow/ZooFlow.vbproj index 5e9cc517..6ef8582a 100644 --- a/ZooFlow/ZooFlow.vbproj +++ b/ZooFlow/ZooFlow.vbproj @@ -51,9 +51,11 @@ + + - ..\packages\NLog.4.5.11\lib\net45\NLog.dll + ..\packages\NLog.4.6.7\lib\net45\NLog.dll @@ -87,8 +89,10 @@ - - + + + + @@ -132,9 +136,7 @@ - - - + frmConfigDatabase.vb @@ -162,6 +164,7 @@ Resources.resx True + SettingsSingleFileGenerator Settings.Designer.vb @@ -206,7 +209,20 @@ {903B2D7D-3B80-4BE9-8713-7447B704E1B0} Logging + + {81cac44f-3711-4c8f-ae98-e02a7448782a} + ZooFlow + + + {1fba063d-60a5-4fc8-a529-a3d1ecfd640c} + ClipboardWatcher + + + {5efaef9b-90b9-4f05-9f70-f79ad77fff86} + Windows + +