Index: DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/Version/VersionComparer.cs =================================================================== diff -u --- DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/Version/VersionComparer.cs (revision 0) +++ DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/Version/VersionComparer.cs (revision 6903) @@ -0,0 +1,39 @@ +// Copyright (C) Stichting Deltares 2025. All rights reserved. +// +// This file is part of the application DAM - UI. +// +// DAM - UI is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +namespace Deltares.Dam.Data.Version; + +public abstract class VersionComparer +{ + /// + /// Test is a current version number is greater or equal to a required version number + /// + /// The current version + /// The required version + /// True if greater or equal, else false + public static bool IsVersionGreaterOrEqual(string currentVersion, string requiredVersion) + { + var current = new System.Version(currentVersion); + var required = new System.Version(requiredVersion); + + return current >= required; + } +} \ No newline at end of file Index: DamClients/DamUI/trunk/src/Dam/Application/Program.cs =================================================================== diff -u -r6436 -r6903 --- DamClients/DamUI/trunk/src/Dam/Application/Program.cs (.../Program.cs) (revision 6436) +++ DamClients/DamUI/trunk/src/Dam/Application/Program.cs (.../Program.cs) (revision 6903) @@ -20,9 +20,13 @@ // All rights reserved. using System; +using System.Collections.Generic; using System.Drawing; using System.Text; +using System.Windows.Forms; using Deltares.Dam.Data.License; +using Deltares.Dam.Data.Registry; +using Deltares.Dam.Data.Version; using Deltares.Dam.Forms; using Deltares.Geometry.Forms; using Deltares.Geotechnics.Forms; @@ -61,6 +65,8 @@ private static void Start() { + VerifyInstallation(); + DamLicense.CheckoutLicense(dAuthFeature, info.AssemblyVersion); // Parameters are used for splash screen @@ -84,6 +90,55 @@ DamLicense.CheckinLicense(); } + /// + /// Check if the application is properly installed by verifying the required versions + /// of Common Files and DS_Flex in the registry. + /// If not, show an error message and exit the application. + /// + private static void VerifyInstallation() + { + const string requiredVersionCommonFiles = "26.1"; + const string registryPathCommonFiles = "SOFTWARE\\WOW6432Node\\Deltares\\"; + const string registryKeyCommonFiles = "Common Version"; + const string requiredVersionDsFlex = "7.9"; + const string registryPathDsFlex = "SOFTWARE\\WOW6432Node\\WL | Delft Hydraulics\\DS_Flex\\"; + const string registryKeyDsFlex = "InstallerVersion"; + + var errorMessages = new List(); + // Check version of Common Files + string versionCommonFiles = RegistryReader.GetRegistryValueFromLocalMachine(registryPathCommonFiles, registryKeyCommonFiles); + if (string.IsNullOrEmpty(versionCommonFiles)) + { + errorMessages.Add("Common Files not found."); + } else if (!VersionComparer.IsVersionGreaterOrEqual(versionCommonFiles, requiredVersionCommonFiles)) + { + errorMessages.Add("Common files version is outdated: " + versionCommonFiles + + ". Required version is " + requiredVersionCommonFiles + " or higher."); + } + // Check version of DS_Flex + string versionDsFlex = RegistryReader.GetRegistryValueFromLocalMachine(registryPathDsFlex, registryKeyDsFlex); + if (string.IsNullOrEmpty(versionCommonFiles)) + { + errorMessages.Add("DS_Flex not found."); + } else if (!VersionComparer.IsVersionGreaterOrEqual(versionDsFlex, requiredVersionDsFlex)) + { + errorMessages.Add("DS_Flex version is outdated: " + versionDsFlex + + ". Required version is " + requiredVersionDsFlex + " or higher."); + } + if (errorMessages.Count > 0) + { + var errorMessage = new StringBuilder(); + errorMessage.AppendLine("The application cannot be started because it is not properly installed. Please reinstall the application."); + foreach (string msg in errorMessages) + { + errorMessage.AppendLine(msg); + } + + MessageBox.Show(errorMessage.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + Environment.Exit(0); + } + } + private static void MainFormTextChanged(object sender, EventArgs eventArgs) { var mainForm = sender as MainForm; Index: DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data.Tests/Version/VersionComparerTests.cs =================================================================== diff -u --- DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data.Tests/Version/VersionComparerTests.cs (revision 0) +++ DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data.Tests/Version/VersionComparerTests.cs (revision 6903) @@ -0,0 +1,62 @@ +// Copyright (C) Stichting Deltares 2025. All rights reserved. +// +// This file is part of the application DAM - UI. +// +// DAM - UI is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; +using Deltares.Dam.Data.Version; +using NUnit.Framework; + +namespace Deltares.Dam.Data.Tests.Version +{ + [TestFixture] + public class VersionComparerTests + { + [Test] + public void IsVersionGreaterOrEqual_ReturnsTrue_WhenCurrentIsGreater() + { + Assert.That(VersionComparer.IsVersionGreaterOrEqual("7.8.1.2", "7.8.0.0"), Is.True); + } + + [Test] + public void IsVersionGreaterOrEqual_ReturnsTrue_WhenCurrentIsEqual() + { + Assert.That(VersionComparer.IsVersionGreaterOrEqual("7.8.0.0", "7.8.0.0"), Is.True); + } + + [Test] + public void IsVersionGreaterOrEqual_ReturnsFalse_WhenCurrentIsLess() + { + Assert.That(VersionComparer.IsVersionGreaterOrEqual("7.7.9.9", "7.8.0.0"), Is.False); + } + + [Test] + public void IsVersionGreaterOrEqual_ReturnsTrue_WhenCurrentHasFewerSegmentsButIsEqual() + { + Assert.That(VersionComparer.IsVersionGreaterOrEqual("7.8.1", "7.8.1.0"), Is.False); + } + + [Test] + public void IsVersionGreaterOrEqual_ThrowsFormatException_WhenVersionIsInvalid() + { + Assert.Throws(() => VersionComparer.IsVersionGreaterOrEqual("invalid", "7.8.0.0")); + Assert.Throws(() => VersionComparer.IsVersionGreaterOrEqual("7.8.0.0", "invalid")); + } + } +} \ No newline at end of file Index: DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data.Tests/Registry/RegistryReaderTests.cs =================================================================== diff -u --- DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data.Tests/Registry/RegistryReaderTests.cs (revision 0) +++ DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data.Tests/Registry/RegistryReaderTests.cs (revision 6903) @@ -0,0 +1,81 @@ +// Copyright (C) Stichting Deltares 2025. All rights reserved. +// +// This file is part of the application DAM - UI. +// +// DAM - UI is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using Deltares.Dam.Data.Registry; +using Microsoft.Win32; +using NUnit.Framework; + +namespace Deltares.Dam.Data.Tests.Registry +{ + [TestFixture] + public class RegistryReaderTests + { + private const string testKeyPath = @"SOFTWARE\\DeltaresDamTest"; + private const string testValueName = "TestValue"; + private const string testValueContent = "TestContent"; + + [SetUp] + public void SetUp() + { + using RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(testKeyPath); + key!.SetValue(testValueName, testValueContent); + } + + [TearDown] + public void TearDown() + { + Microsoft.Win32.Registry.CurrentUser.DeleteSubKey(testKeyPath, false); + } + + [Test] + public void GetRegistryValue_ReturnsValue_WhenKeyAndValueExist() + { + string result = RegistryReader.GetRegistryValueFromCurrentUser(testKeyPath, testValueName); + Assert.That(result, Is.EqualTo(testValueContent)); + } + + [Test] + public void GetRegistryValue_ReturnsEmpty_WhenKeyDoesNotExist() + { + string result = RegistryReader.GetRegistryValueFromCurrentUser("SOFTWARE\\NonExistentKey", testValueName); + Assert.That(result, Is.EqualTo(string.Empty)); + } + + [Test] + public void GetRegistryValue_ReturnsEmpty_WhenValueDoesNotExist() + { + string result = RegistryReader.GetRegistryValueFromCurrentUser(testKeyPath, "NonExistentValue"); + Assert.That(result, Is.EqualTo(string.Empty)); + } + + [Test] + public void GetRegistryValue_ReturnsStringRepresentation_WhenValueIsNotString() + { + using (RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(testKeyPath, true)) + { + key!.SetValue("VersionValue", "7.8.0.0", RegistryValueKind.String); + } + + string result = RegistryReader.GetRegistryValueFromCurrentUser(testKeyPath, "VersionValue"); + Assert.That(result, Is.EqualTo("7.8.0.0")); + } + } +} \ No newline at end of file Index: DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/Registry/RegistryReader.cs =================================================================== diff -u --- DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/Registry/RegistryReader.cs (revision 0) +++ DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/Registry/RegistryReader.cs (revision 6903) @@ -0,0 +1,66 @@ +// Copyright (C) Stichting Deltares 2025. All rights reserved. +// +// This file is part of the application DAM - UI. +// +// DAM - UI is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using Microsoft.Win32; + +namespace Deltares.Dam.Data.Registry; + +public abstract class RegistryReader +{ + /// + /// Reads a string value from the Windows registry for the local machine. + /// + /// The path to the key + /// The name of the key + /// The value or empty string if key is not found + public static string GetRegistryValueFromLocalMachine(string registryPath, string valueName) + { + using RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(registryPath); + return GetRegistryValue(key, valueName); + } + + /// + /// Reads a string value from the Windows registry for the current user. + /// + /// The path to the key + /// The name of the key + /// The value or empty string if key is not found + public static string GetRegistryValueFromCurrentUser(string registryPath, string valueName) + { + using RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(registryPath); + return GetRegistryValue(key, valueName); + } + + private static string GetRegistryValue(RegistryKey key, string valueName) + { + var stringValue = ""; + if (key != null) + { + object value = key.GetValue(valueName); + if (value != null) + { + stringValue = value.ToString(); + } + } + + return stringValue; + } +} \ No newline at end of file