From e4df7284a7b1247fec4969c78f7efd0778b50527 Mon Sep 17 00:00:00 2001 From: TomKovac Date: Tue, 27 Jun 2023 12:49:31 +0200 Subject: [PATCH 1/3] Create draft PR for #4 From d0edc68e3ed83c63b356bfb8e858700937a77939 Mon Sep 17 00:00:00 2001 From: TomKovac <61820360+TomKovac@users.noreply.github.com> Date: Wed, 28 Jun 2023 11:14:45 +0200 Subject: [PATCH 2/3] loading dll dynamically --- src/tia2ax/V18_0/ApiResolver/ApiResolver.cs | 56 ++++++++++++++++----- src/tia2ax/V18_0/App.config | 6 +++ src/tia2ax/V18_0/Program.cs | 5 ++ src/tia2ax/V18_0/Utils/TiaOpeness.cs | 52 +++++++++---------- src/tia2ax/V18_0/V18_0_tia2ax.csproj | 9 ++-- src/tia2axtool/tia2axtool.csproj | 3 +- 6 files changed, 89 insertions(+), 42 deletions(-) create mode 100644 src/tia2ax/V18_0/App.config diff --git a/src/tia2ax/V18_0/ApiResolver/ApiResolver.cs b/src/tia2ax/V18_0/ApiResolver/ApiResolver.cs index 3cff8c7..88c41da 100644 --- a/src/tia2ax/V18_0/ApiResolver/ApiResolver.cs +++ b/src/tia2ax/V18_0/ApiResolver/ApiResolver.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Reflection; using System.Resources; +using System.Security.AccessControl; using System.Text; namespace Tia2Ax.Utils @@ -15,16 +16,14 @@ namespace Tia2Ax.Utils /// public static class ApiResolver { - /// /// Required min version of engineering dll /// public const string StrRequiredVersion = "V18.0"; private const string BasePath = "SOFTWARE\\Siemens\\Automation\\Openness\\"; - private const string ReferencedAssembly = "Siemens.Engineering"; - private const string ReferencedHmiAssembly = "Siemens.Engineering.Hmi"; private static string _assemblyPath = ""; - private static string _assemblyPathHmi = ""; + private const string LibraryKey = "SOFTWARE\\Siemens\\Automation\\Openness\\18.0\\PublicAPI\\18.0.0.0"; + private const string LibraryName = "Siemens.Engineering"; /// /// Get version info from registry key @@ -109,13 +108,18 @@ public static bool IsOpennessInstalled() private static string GetLibraryFilePath() { - var engineeringVersion = GetEngineeringVersions(); - - var requiredVersion = (from version in engineeringVersion - where Convert.ToDecimal(version) >= Convert.ToDecimal(StrRequiredVersion.Substring(1, 4)) - select version).FirstOrDefault(); - - return requiredVersion; + using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)) + { + using (var registryKey = baseKey.OpenSubKey(LibraryKey, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey)) + { + var libraryFilePath = registryKey?.GetValue(LibraryName) as string; + if (!string.IsNullOrWhiteSpace(libraryFilePath) && File.Exists(libraryFilePath)) + { + return libraryFilePath; + } + } + } + return null; } @@ -132,7 +136,7 @@ public static bool IsTiaInstalled() { foreach (var version in EngineeringVersions) { - if(version == StrRequiredVersion) + if(version == StrRequiredVersion.Substring(1, 4)) { return true; } @@ -147,5 +151,33 @@ public static bool IsTiaInstalled() } return false; } + + public static Assembly AssemblyResolver(object sender, ResolveEventArgs args) + { + var lookupName = new AssemblyName(args.Name); + if (lookupName.Name.Equals(LibraryName, StringComparison.OrdinalIgnoreCase)) + { + var libraryFilePath = GetLibraryFilePath(); + if (!string.IsNullOrWhiteSpace(libraryFilePath)) + { + var suggestedName = AssemblyName.GetAssemblyName(libraryFilePath); + return Assembly.Load(suggestedName); + } + } + return null; + } + public static Assembly LoadOpenessAssembly() + { + var libraryFilePath = GetLibraryFilePath(); + if (!string.IsNullOrWhiteSpace(libraryFilePath)) + { + var suggestedName = AssemblyName.GetAssemblyName(libraryFilePath); + Assembly assembly = Assembly.Load(suggestedName); + return assembly; + } + return null; + } + + } } diff --git a/src/tia2ax/V18_0/App.config b/src/tia2ax/V18_0/App.config new file mode 100644 index 0000000..17b40ec --- /dev/null +++ b/src/tia2ax/V18_0/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/tia2ax/V18_0/Program.cs b/src/tia2ax/V18_0/Program.cs index 8ea1290..2704cce 100644 --- a/src/tia2ax/V18_0/Program.cs +++ b/src/tia2ax/V18_0/Program.cs @@ -3,6 +3,7 @@ using System; using System.Resources; using Tia2Ax.Utils; +using System.Reflection; namespace tia2ax { @@ -38,6 +39,10 @@ private static void GoAhead(Options options) { if (TiaOpeness.CheckPrerequisities()) { + AppDomain.CurrentDomain.AssemblyResolve += ApiResolver.AssemblyResolver; + + ApiResolver.LoadOpenessAssembly(); + var traceWriter = new Tia2Ax.Interfaces.TraceWriter(); var apiWrapper = new Tia2Ax.Interfaces.ApiWrapper(traceWriter); diff --git a/src/tia2ax/V18_0/Utils/TiaOpeness.cs b/src/tia2ax/V18_0/Utils/TiaOpeness.cs index 0cc57a7..4fa4791 100644 --- a/src/tia2ax/V18_0/Utils/TiaOpeness.cs +++ b/src/tia2ax/V18_0/Utils/TiaOpeness.cs @@ -9,32 +9,32 @@ public static class TiaOpeness { public static bool CheckPrerequisities() { - //try - //{ - // if (!ApiResolver.IsOpennessInstalled()) - // { - // throw new Exception( - // $"The TIA Portal Openness version required {ApiResolver.StrRequiredVersion}{Environment.NewLine} is not installed."); - // } - //} - //catch (Exception e) - //{ - // Console.WriteLine(e); - // throw; - //} - //try - //{ - // if (!ApiResolver.IsTiaInstalled()) - // { - // throw new Exception( - // $"The TIA Portal version required {ApiResolver.StrRequiredVersion}{Environment.NewLine} is not installed."); - // } - //} - //catch (Exception e) - //{ - // Console.WriteLine(e); - // throw; - //} + try + { + if (!ApiResolver.IsOpennessInstalled()) + { + throw new Exception( + $"The TIA Portal Openness version required {ApiResolver.StrRequiredVersion}{Environment.NewLine} is not installed."); + } + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + try + { + if (!ApiResolver.IsTiaInstalled()) + { + throw new Exception( + $"The TIA Portal version required {ApiResolver.StrRequiredVersion}{Environment.NewLine} is not installed."); + } + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } return true; } } diff --git a/src/tia2ax/V18_0/V18_0_tia2ax.csproj b/src/tia2ax/V18_0/V18_0_tia2ax.csproj index 8fe5645..ef726dc 100644 --- a/src/tia2ax/V18_0/V18_0_tia2ax.csproj +++ b/src/tia2ax/V18_0/V18_0_tia2ax.csproj @@ -1,5 +1,4 @@  - Exe net4.8 @@ -24,8 +23,12 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + + + Always + diff --git a/src/tia2axtool/tia2axtool.csproj b/src/tia2axtool/tia2axtool.csproj index 1615dd8..4a380ce 100644 --- a/src/tia2axtool/tia2axtool.csproj +++ b/src/tia2axtool/tia2axtool.csproj @@ -19,5 +19,6 @@ - + + From 28c1e199bc362232202437a62b16567d08125ad9 Mon Sep 17 00:00:00 2001 From: TomKovac <61820360+TomKovac@users.noreply.github.com> Date: Wed, 28 Jun 2023 12:25:57 +0200 Subject: [PATCH 3/3] Added copying of the local Opennes dll --- src/tia2ax/V18_0/ApiResolver/ApiResolver.cs | 51 --------------------- src/tia2ax/V18_0/App.config | 6 --- src/tia2ax/V18_0/Program.cs | 4 -- src/tia2ax/V18_0/V18_0_tia2ax.csproj | 9 +--- src/tia2axtool/Program.cs | 41 ++++++++++++++--- 5 files changed, 36 insertions(+), 75 deletions(-) delete mode 100644 src/tia2ax/V18_0/App.config diff --git a/src/tia2ax/V18_0/ApiResolver/ApiResolver.cs b/src/tia2ax/V18_0/ApiResolver/ApiResolver.cs index 88c41da..0d7faa1 100644 --- a/src/tia2ax/V18_0/ApiResolver/ApiResolver.cs +++ b/src/tia2ax/V18_0/ApiResolver/ApiResolver.cs @@ -4,10 +4,7 @@ using System.Collections.ObjectModel; using System.IO; using System.Linq; -using System.Reflection; -using System.Resources; using System.Security.AccessControl; -using System.Text; namespace Tia2Ax.Utils { @@ -21,7 +18,6 @@ public static class ApiResolver /// public const string StrRequiredVersion = "V18.0"; private const string BasePath = "SOFTWARE\\Siemens\\Automation\\Openness\\"; - private static string _assemblyPath = ""; private const string LibraryKey = "SOFTWARE\\Siemens\\Automation\\Openness\\18.0\\PublicAPI\\18.0.0.0"; private const string LibraryName = "Siemens.Engineering"; @@ -56,25 +52,6 @@ where Convert.ToDecimal(item.Substring(0, 4)) >= Convert.ToDecimal(StrRequiredVe return new List(); } - - /// - /// Retrieve the path from assembly by version - /// - /// - /// - /// - public static string GetAssemblyPath(string version, string assembly) - { - var libraries = OpennessLibraries.GetOpennessLibraries(); - var portalVersion = new Version(version); - var apiVersion = new Version(assembly); - _assemblyPath = libraries.Where(e => e.TiaPortalVersion.Major == portalVersion.Major && - e.TiaPortalVersion.Minor == portalVersion.Minor).SingleOrDefault(e => e.PublicApiVersion.Major == apiVersion.Major && - e.PublicApiVersion.Minor == apiVersion.Minor)?.LibraryFilePath; - - return null; - } - private static RegistryKey GetRegistryKey(string keyName) { RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64); @@ -151,33 +128,5 @@ public static bool IsTiaInstalled() } return false; } - - public static Assembly AssemblyResolver(object sender, ResolveEventArgs args) - { - var lookupName = new AssemblyName(args.Name); - if (lookupName.Name.Equals(LibraryName, StringComparison.OrdinalIgnoreCase)) - { - var libraryFilePath = GetLibraryFilePath(); - if (!string.IsNullOrWhiteSpace(libraryFilePath)) - { - var suggestedName = AssemblyName.GetAssemblyName(libraryFilePath); - return Assembly.Load(suggestedName); - } - } - return null; - } - public static Assembly LoadOpenessAssembly() - { - var libraryFilePath = GetLibraryFilePath(); - if (!string.IsNullOrWhiteSpace(libraryFilePath)) - { - var suggestedName = AssemblyName.GetAssemblyName(libraryFilePath); - Assembly assembly = Assembly.Load(suggestedName); - return assembly; - } - return null; - } - - } } diff --git a/src/tia2ax/V18_0/App.config b/src/tia2ax/V18_0/App.config deleted file mode 100644 index 17b40ec..0000000 --- a/src/tia2ax/V18_0/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/tia2ax/V18_0/Program.cs b/src/tia2ax/V18_0/Program.cs index 2704cce..ad23005 100644 --- a/src/tia2ax/V18_0/Program.cs +++ b/src/tia2ax/V18_0/Program.cs @@ -39,10 +39,6 @@ private static void GoAhead(Options options) { if (TiaOpeness.CheckPrerequisities()) { - AppDomain.CurrentDomain.AssemblyResolve += ApiResolver.AssemblyResolver; - - ApiResolver.LoadOpenessAssembly(); - var traceWriter = new Tia2Ax.Interfaces.TraceWriter(); var apiWrapper = new Tia2Ax.Interfaces.ApiWrapper(traceWriter); diff --git a/src/tia2ax/V18_0/V18_0_tia2ax.csproj b/src/tia2ax/V18_0/V18_0_tia2ax.csproj index ef726dc..e74bb5b 100644 --- a/src/tia2ax/V18_0/V18_0_tia2ax.csproj +++ b/src/tia2ax/V18_0/V18_0_tia2ax.csproj @@ -2,8 +2,6 @@ Exe net4.8 - @@ -24,11 +22,6 @@ - - - - - Always - + diff --git a/src/tia2axtool/Program.cs b/src/tia2axtool/Program.cs index 718f9a7..cd3bdc3 100644 --- a/src/tia2axtool/Program.cs +++ b/src/tia2axtool/Program.cs @@ -1,18 +1,47 @@ -using System.Diagnostics; +using Microsoft.Win32; +using System.Diagnostics; using System.Reflection; +using System.Security.AccessControl; namespace tia2axtool { internal class Program { + private const string LibraryKey = "SOFTWARE\\Siemens\\Automation\\Openness\\18.0\\PublicAPI\\18.0.0.0"; + private const string LibraryName = "Siemens.Engineering"; + static void Main(string[] args) { - // This is a workaround to make a .net48 assembly work as dotnet tool - var entry = new FileInfo(Assembly.GetEntryAssembly().Location); - var folder = entry.Directory.FullName; + string libraryPath = GetLibraryFilePath(); + if (!string.IsNullOrEmpty(libraryPath)) + { + // This is a workaround to get the local dll for the Openness + var entry = new FileInfo(Assembly.GetEntryAssembly().Location); + var folder = entry.Directory.FullName; + File.Copy(libraryPath, Path.Combine(folder, LibraryName + ".dll"), true); + File.Copy(libraryPath.Replace("dll", "xml"), Path.Combine(folder, LibraryName + ".xml"), true); + + // This is a workaround to make a .net48 assembly work as dotnet tool - var exePath = Path.Combine(folder, "V18_0_tia2ax.exe"); - Process.Start(new ProcessStartInfo(exePath) { Arguments = string.Join(" ", args) }); + var exePath = Path.Combine(folder, "V18_0_tia2ax.exe"); + Process.Start(new ProcessStartInfo(exePath) { Arguments = string.Join(" ", args) }); + } + } + + private static string GetLibraryFilePath() + { + using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)) + { + using (var registryKey = baseKey.OpenSubKey(LibraryKey, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey)) + { + var libraryFilePath = registryKey?.GetValue(LibraryName) as string; + if (!string.IsNullOrWhiteSpace(libraryFilePath) && File.Exists(libraryFilePath)) + { + return libraryFilePath; + } + } + } + return null; } } } \ No newline at end of file