diff --git a/TiaGitHandler/Program.cs b/TiaGitHandler/Program.cs index d3c2d9b5..ddd3a3c9 100644 --- a/TiaGitHandler/Program.cs +++ b/TiaGitHandler/Program.cs @@ -19,6 +19,7 @@ using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using TiaGitHandler.Properties; using Application = System.Windows.Application; +using InvalidOperationException = System.InvalidOperationException; using MessageBox = System.Windows.Forms.MessageBox; using OpenFileDialog = Microsoft.Win32.OpenFileDialog; @@ -96,6 +97,23 @@ static void Main(string[] args) Console.WriteLine("Bitte S7 projekt als Parameter angeben!"); return; } + var version = file.Substring(file.Length - 2, 2) + ".0"; + try + { + TiaOpennessWhitelist.EnsureWhitelistEntry(version); + } + catch (InvalidOperationException ex) + { + Console.WriteLine($"Cannot set TIA whitelist registry entry: {ex.Message}"); + } + catch (SecurityException ex) + { + Console.WriteLine($"Security exception cannot set TIA whitelist registry entry: {ex.Message}"); + } + catch (UnauthorizedAccessException ex) + { + Console.WriteLine($"Unauthorized access exception cannot set TIA whitelist registry entry: {ex.Message}"); + } if (Path.GetExtension(file) == ".ap15_1" || Path.GetExtension(file) == ".ap16") { @@ -120,16 +138,33 @@ static void Main(string[] args) } exportPath = Path.GetDirectoryName(file); - exportPath = Path.GetFullPath(Path.Combine(exportPath, "..\\Export")); + exportPath = Path.GetFullPath(Path.Combine(exportPath, "..\\out\\Export")); } else if (res != null) { var ver = ask.Result as string; - prj = Projects.AttachProject(ver); + + try + { + TiaOpennessWhitelist.EnsureWhitelistEntry(ver + ".0"); + } + catch (InvalidOperationException ex) + { + Console.WriteLine($"Cannot set TIA whitelist registry entry: {ex.Message}"); + } + catch (SecurityException ex) + { + Console.WriteLine($"Authorization context to low cannot set TIA whitelist registry entry: {ex.Message}"); + } + catch (UnauthorizedAccessException ex) + { + Console.WriteLine($"Unauthorized access exception cannot set TIA whitelist registry entry: {ex.Message}"); + } + prj = Projects.AttachProject(ver); exportPath = Path.GetDirectoryName(prj.ProjectFile); - exportPath = Path.GetFullPath(Path.Combine(exportPath, "..\\Export")); + exportPath = Path.GetFullPath(Path.Combine(exportPath, "..\\out\\Export")); } else { @@ -165,6 +200,9 @@ static void Main(string[] args) user = args[3]; if (args.Length > 4) password = args[4]; + if (args.Length > 5) + exportPath = args[5]; + } if (prj == null) @@ -179,6 +217,26 @@ static void Main(string[] args) } } + var version = file.Substring(file.Length - 2, 2) + ".0"; + + try + { + TiaOpennessWhitelist.EnsureWhitelistEntry(version); + } + catch (InvalidOperationException ex) + { + Console.WriteLine($"Cannot set TIA whitelist registry entry: {ex.Message}"); + } + catch (SecurityException ex) + { + Console.WriteLine($"Security exception cannot set TIA whitelist registry entry: {ex.Message}"); + } + catch (UnauthorizedAccessException ex) + { + Console.WriteLine($"Unauthorized access exception cannot set TIA whitelist registry entry: {ex.Message}"); + } + + if (attach) { if (file.EndsWith("20")) diff --git a/TiaGitHandler/TiaOpennessWhitelist.cs b/TiaGitHandler/TiaOpennessWhitelist.cs new file mode 100644 index 00000000..fa4c4f19 --- /dev/null +++ b/TiaGitHandler/TiaOpennessWhitelist.cs @@ -0,0 +1,91 @@ +using Microsoft.Win32; +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Security.Cryptography; + +namespace TiaGitHandler +{ + public static class TiaOpennessWhitelist + { + /// + /// Retrieves the path to the currently executing .exe + /// + private static string GetApplicationPath() + { + // use the executing assembly’s location + var path = Assembly.GetExecutingAssembly().Location; + + if (!string.IsNullOrEmpty(path)) + return path; + + // use the main module’s file name of the current process + using (var proc = Process.GetCurrentProcess()) + { + path = proc.MainModule?.FileName; + if (!string.IsNullOrEmpty(path)) + return path; + } + + throw new InvalidOperationException("Could not determine the application path."); + } + + /// + /// Ensures that a whitelist entry exists and is up-to-date. + /// Creates or updates the entry only if Path, DateModified, or FileHash differ. + /// + /// TIA Openness version, e.g. "V16.0". + /// True if the entry was created or updated; false if it was already current. + public static bool EnsureWhitelistEntry(string tiaVersion) + { + // 1. determine the application path + var applicationPath = GetApplicationPath(); + var exeName = Path.GetFileName(applicationPath); + + // 2. Compute the desired DateModified value + var fileInfo = new FileInfo(applicationPath); + var desiredDate = fileInfo.LastWriteTimeUtc + .ToString("yyyy/MM/dd HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture); + + // 3. Compute the desired FileHash value (SHA-256, Base64) + byte[] hashBytes; + using (var sha = SHA256.Create()) + using (var stream = File.OpenRead(applicationPath)) + hashBytes = sha.ComputeHash(stream); + var desiredHash = Convert.ToBase64String(hashBytes); + + // 4. Construct the registry subkey path + var subKey = $@"SOFTWARE\Siemens\Automation\Openness\{tiaVersion}\Whitelist\{exeName}\Entry"; + + // 5. Open or create the registry key + using (var entryKey = Registry.LocalMachine.OpenSubKey(subKey, writable: true) + ?? Registry.LocalMachine.CreateSubKey(subKey, writable: true)) + { + if (entryKey == null) + throw new InvalidOperationException($"Could not create or open registry key: HKLM\\{subKey}"); + + // 6. Read existing values + var currentPath = entryKey.GetValue("Path") as string; + var currentDate = entryKey.GetValue("DateModified") as string; + var currentHash = entryKey.GetValue("FileHash") as string; + + // 7. Check if any value differs + var needsUpdate = + currentPath != applicationPath || + currentDate != desiredDate || + currentHash != desiredHash; + + if (!needsUpdate) + return false; // already up-to-date + + // 8. Write the new values + entryKey.SetValue("Path", applicationPath, RegistryValueKind.String); + entryKey.SetValue("DateModified", desiredDate, RegistryValueKind.String); + entryKey.SetValue("FileHash", desiredHash, RegistryValueKind.String); + + return true; + } + } + } +}