From e15ef061a2d38ef05e1dc79ade56e6d75b54f3f6 Mon Sep 17 00:00:00 2001 From: Andre Lafleur Date: Fri, 6 Feb 2026 18:30:20 +0800 Subject: [PATCH 1/3] refactor: move VCard and VCardReader to Shared project Move the shared VCard parsing classes from the individual sample folders to the Shared project so both ImageExtractorSample and CardholderFieldsExtractorSample use the same implementation. --- Samples/Genetec.Dap.CodeSamples.sln | 1 + Samples/Shared/Shared.projitems | 2 + .../VCard.cs | 0 .../VCardReader.cs | 0 .../CardholderFieldsExtractorSample.csproj | 2 + .../ImageExtractorSample/VCard.cs | 20 ------ .../ImageExtractorSample/VCardReader.cs | 62 ------------------- 7 files changed, 5 insertions(+), 82 deletions(-) rename Samples/{Workspace SDK/CardholderFieldsExtractorSample => Shared}/VCard.cs (100%) rename Samples/{Workspace SDK/CardholderFieldsExtractorSample => Shared}/VCardReader.cs (100%) delete mode 100644 Samples/Workspace SDK/ImageExtractorSample/VCard.cs delete mode 100644 Samples/Workspace SDK/ImageExtractorSample/VCardReader.cs diff --git a/Samples/Genetec.Dap.CodeSamples.sln b/Samples/Genetec.Dap.CodeSamples.sln index 0f809f96..015b0d44 100644 --- a/Samples/Genetec.Dap.CodeSamples.sln +++ b/Samples/Genetec.Dap.CodeSamples.sln @@ -1601,6 +1601,7 @@ Global Shared\Shared.projitems*{5a217bbf-eafa-4f52-b81a-02c4232da68e}*SharedItemsImports = 5 Shared\Shared.projitems*{5a3ca774-e381-4e87-b8d9-091644b52222}*SharedItemsImports = 5 Shared\Shared.projitems*{5d7b3be5-9b6a-4723-a316-78918ade866a}*SharedItemsImports = 5 + Shared\Shared.projitems*{5e1abc70-44e0-437c-a9ea-90bfd7bb7449}*SharedItemsImports = 5 Shared\Shared.projitems*{62ff8f2f-fe3a-4c9e-ab42-fc58184971e0}*SharedItemsImports = 5 Shared\Shared.projitems*{63c46961-ccb1-4dd1-a292-8cf1de362f94}*SharedItemsImports = 5 Shared\Shared.projitems*{691fb77e-e114-49bf-8fcf-c0957696e305}*SharedItemsImports = 5 diff --git a/Samples/Shared/Shared.projitems b/Samples/Shared/Shared.projitems index 9ebcf321..279bcfae 100644 --- a/Samples/Shared/Shared.projitems +++ b/Samples/Shared/Shared.projitems @@ -16,5 +16,7 @@ + + \ No newline at end of file diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/VCard.cs b/Samples/Shared/VCard.cs similarity index 100% rename from Samples/Workspace SDK/CardholderFieldsExtractorSample/VCard.cs rename to Samples/Shared/VCard.cs diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/VCardReader.cs b/Samples/Shared/VCardReader.cs similarity index 100% rename from Samples/Workspace SDK/CardholderFieldsExtractorSample/VCardReader.cs rename to Samples/Shared/VCardReader.cs diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/CardholderFieldsExtractorSample.csproj b/Samples/Workspace SDK/CardholderFieldsExtractorSample/CardholderFieldsExtractorSample.csproj index 82c10b39..236bdf87 100644 --- a/Samples/Workspace SDK/CardholderFieldsExtractorSample/CardholderFieldsExtractorSample.csproj +++ b/Samples/Workspace SDK/CardholderFieldsExtractorSample/CardholderFieldsExtractorSample.csproj @@ -77,4 +77,6 @@ + + diff --git a/Samples/Workspace SDK/ImageExtractorSample/VCard.cs b/Samples/Workspace SDK/ImageExtractorSample/VCard.cs deleted file mode 100644 index 44c893e1..00000000 --- a/Samples/Workspace SDK/ImageExtractorSample/VCard.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2025 Genetec Inc. -// Licensed under the Apache License, Version 2.0 - -namespace Genetec.Dap.CodeSamples; - -using System.Collections.Generic; -using System.Windows.Media; - -public class VCard -{ - public string FirstName { get; set; } - - public string LastName { get; set; } - - public List Emails { get; } = new List(); - - public string Note { get; set; } - - public ImageSource Picture { get; set; } -} \ No newline at end of file diff --git a/Samples/Workspace SDK/ImageExtractorSample/VCardReader.cs b/Samples/Workspace SDK/ImageExtractorSample/VCardReader.cs deleted file mode 100644 index 8209c34f..00000000 --- a/Samples/Workspace SDK/ImageExtractorSample/VCardReader.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2025 Genetec Inc. -// Licensed under the Apache License, Version 2.0 - -namespace Genetec.Dap.CodeSamples; - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using System.Windows.Media; -using System.Windows.Media.Imaging; - -public class VCardReader -{ - public static VCard ReadVCard(string filePath) - { - string vCardText = File.ReadAllText(filePath); - var vcard = new VCard - { - FirstName = ExtractField(vCardText, "FN:"), - LastName = ExtractField(vCardText, "N:").Split(';')[0], // Assuming last name is the first component in the N: field - Note = ExtractField(vCardText, "NOTE:"), - Picture = ExtractPhoto(vCardText) - }; - - vcard.Emails.AddRange(ExtractEmails(vCardText)); - return vcard; - } - - private static string ExtractField(string vCardText, string fieldName) - { - Match match = Regex.Match(vCardText, $"{fieldName}(.*?)(\n(?![ \t])|\r\n(?![ \t])|$)", RegexOptions.Singleline); - return match.Success ? match.Groups[1].Value.Trim() : string.Empty; - } - - private static List ExtractEmails(string vCardText) - { - MatchCollection matches = Regex.Matches(vCardText, "EMAIL;[^:]+:(.*?)\r?\n"); - return matches.Cast().Select(match => match.Groups[1].Value.Trim()).ToList(); - } - - private static ImageSource ExtractPhoto(string vCardText) - { - Match photoMatch = Regex.Match(vCardText, @"PHOTO;ENCODING=b;TYPE=image/jpeg:(.*?)(\n(?![ \t])|\r\n(?![ \t])|$)", RegexOptions.Singleline); - if (photoMatch.Success) - { - string base64Data = photoMatch.Groups[1].Value.Trim().Replace("\n", "").Replace("\r", ""); - - using var stream = new MemoryStream(Convert.FromBase64String(base64Data)); - var bitmap = new BitmapImage(); - bitmap.BeginInit(); - bitmap.StreamSource = stream; - bitmap.CacheOption = BitmapCacheOption.OnLoad; - bitmap.EndInit(); - bitmap.Freeze(); - return bitmap; - } - - return null; - } -} \ No newline at end of file From 492780ab0834a6baf9817a3e78dcb86766593702 Mon Sep 17 00:00:00 2001 From: Andre Lafleur Date: Fri, 6 Feb 2026 18:30:27 +0800 Subject: [PATCH 2/3] fix: improve ImageExtractorSample module registration Add field to store component reference, add Unregister in Unload, and add ApplicationType check for SecurityDesk and ConfigTool. --- .../SampleImageExtractor.cs | 14 ++++++++------ .../ImageExtractorSample/SampleModule.cs | 17 +++++++++++++---- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Samples/Workspace SDK/ImageExtractorSample/SampleImageExtractor.cs b/Samples/Workspace SDK/ImageExtractorSample/SampleImageExtractor.cs index 9f053b13..809f5dad 100644 --- a/Samples/Workspace SDK/ImageExtractorSample/SampleImageExtractor.cs +++ b/Samples/Workspace SDK/ImageExtractorSample/SampleImageExtractor.cs @@ -3,11 +3,11 @@ namespace Genetec.Dap.CodeSamples; +using Microsoft.Win32; +using Sdk.Workspace.Components.ImageExtractor; using System; using System.Windows.Media; using System.Windows.Media.Imaging; -using Microsoft.Win32; -using Sdk.Workspace.Components.ImageExtractor; public sealed class SampleImageExtractor : ImageExtractor { @@ -17,16 +17,18 @@ public sealed class SampleImageExtractor : ImageExtractor public override Guid UniqueId { get; } = new Guid("5EDBB0B6-8253-433E-99A1-9021E498437A"); - public override ImageSource GetImage() { - var openFileDialog = new OpenFileDialog + var dialog = new OpenFileDialog { Filter = "vCard files (*.vcf)|*.vcf|All files (*.*)|*.*", - Title = "Open vCard File" + Title = "Select vCard File" }; - return openFileDialog.ShowDialog() == true ? VCardReader.ReadVCard(openFileDialog.FileName)?.Picture : null; + if (dialog.ShowDialog() != true) + return null; + + return VCardReader.ReadVCard(dialog.FileName)?.Picture; } public override bool SupportsContext(ImageExtractorContext context) diff --git a/Samples/Workspace SDK/ImageExtractorSample/SampleModule.cs b/Samples/Workspace SDK/ImageExtractorSample/SampleModule.cs index f1f48d88..9401602d 100644 --- a/Samples/Workspace SDK/ImageExtractorSample/SampleModule.cs +++ b/Samples/Workspace SDK/ImageExtractorSample/SampleModule.cs @@ -3,20 +3,29 @@ namespace Genetec.Dap.CodeSamples; +using Genetec.Sdk; using Sdk.Workspace.Modules; public class SampleModule : Module { - static SampleModule() => AssemblyResolver.Initialize(); + private SampleImageExtractor m_imageExtractor; public override void Load() { - var component = new SampleImageExtractor(); - component.Initialize(Workspace); - Workspace.Components.Register(component); + if (Workspace.ApplicationType is ApplicationType.SecurityDesk or ApplicationType.ConfigTool) + { + m_imageExtractor = new SampleImageExtractor(); + m_imageExtractor.Initialize(Workspace); + Workspace.Components.Register(m_imageExtractor); + } } public override void Unload() { + if (m_imageExtractor != null) + { + Workspace.Components.Unregister(m_imageExtractor); + m_imageExtractor = null; + } } } \ No newline at end of file From dca2b0d5428442d0b59e83c0d3687d2f45426a5b Mon Sep 17 00:00:00 2001 From: Andre Lafleur Date: Fri, 6 Feb 2026 18:30:33 +0800 Subject: [PATCH 3/3] fix: improve CardholderFieldsExtractorSample module registration Add field to store component reference, add Unregister in Unload, and add ApplicationType check for SecurityDesk and ConfigTool. --- .../SampleCardholderFieldsExtractor.cs | 28 +++++++++---------- .../SampleModule.cs | 17 +++++++++-- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleCardholderFieldsExtractor.cs b/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleCardholderFieldsExtractor.cs index a5ab9d4e..86fce71d 100644 --- a/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleCardholderFieldsExtractor.cs +++ b/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleCardholderFieldsExtractor.cs @@ -12,30 +12,30 @@ public class SampleCardholderFieldsExtractor : CardholderFieldsExtractor { public override string Name => "Read vCard..."; - public override Guid UniqueId { get; } = new("88F33E43-1E51-4504-95BF-ADD2FBCBA8AD"); // TODO: Replace with your own GUID + public override Guid UniqueId { get; } = new("88F33E43-1E51-4504-95BF-ADD2FBCBA8AD"); public override CardholderFields GetFields(CardholderFieldsExtractorData data) { - var openFileDialog = new OpenFileDialog + var dialog = new OpenFileDialog { Filter = "vCard files (*.vcf)|*.vcf|All files (*.*)|*.*", Title = "Open vCard File" }; - if (openFileDialog.ShowDialog() == true) + if (dialog.ShowDialog() != true) + return null; + + VCard vCardInfo = VCardReader.ReadVCard(dialog.FileName); + if (vCardInfo != null) { - VCard vCardInfo = VCardReader.ReadVCard(openFileDialog.FileName); - if (vCardInfo != null) + return new CardholderFields { - return new CardholderFields - { - FirstName = vCardInfo.FirstName, - LastName = vCardInfo.LastName, - Email = vCardInfo.Emails.FirstOrDefault(), - Picture = vCardInfo.Picture, - Description = vCardInfo.Note - }; - } + FirstName = vCardInfo.FirstName, + LastName = vCardInfo.LastName, + Email = vCardInfo.Emails.FirstOrDefault(), + Picture = vCardInfo.Picture, + Description = vCardInfo.Note + }; } return null; diff --git a/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleModule.cs b/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleModule.cs index 726bb2e7..b38a195c 100644 --- a/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleModule.cs +++ b/Samples/Workspace SDK/CardholderFieldsExtractorSample/SampleModule.cs @@ -3,18 +3,29 @@ namespace Genetec.Dap.CodeSamples; +using Genetec.Sdk; using Sdk.Workspace.Modules; public class SampleModule : Module { + private SampleCardholderFieldsExtractor m_extractor; + public override void Load() { - var component = new SampleCardholderFieldsExtractor(); - component.Initialize(Workspace); - Workspace.Components.Register(component); + if (Workspace.ApplicationType is ApplicationType.SecurityDesk or ApplicationType.ConfigTool) + { + m_extractor = new SampleCardholderFieldsExtractor(); + m_extractor.Initialize(Workspace); + Workspace.Components.Register(m_extractor); + } } public override void Unload() { + if (m_extractor != null) + { + Workspace.Components.Unregister(m_extractor); + m_extractor = null; + } } } \ No newline at end of file