diff --git a/Samples/Genetec.Dap.CodeSamples.sln b/Samples/Genetec.Dap.CodeSamples.sln
index 0f809f9..dca4156 100644
--- a/Samples/Genetec.Dap.CodeSamples.sln
+++ b/Samples/Genetec.Dap.CodeSamples.sln
@@ -234,6 +234,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerInformationSample", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerSample", "Platform SDK\ServerSample\ServerSample.csproj", "{3451F54A-A0CE-704D-194A-2769C953B0A9}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceProviderSample", "Platform SDK\ResourceProviderSample\ResourceProviderSample.csproj", "{A46BCB50-782B-4946-9620-F90DE462CC30}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_NET481|Any CPU = Debug_NET481|Any CPU
@@ -1456,6 +1458,18 @@ Global
{3451F54A-A0CE-704D-194A-2769C953B0A9}.Release_NET8|Any CPU.Build.0 = Release_NET8|Any CPU
{3451F54A-A0CE-704D-194A-2769C953B0A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3451F54A-A0CE-704D-194A-2769C953B0A9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Debug_NET481|Any CPU.ActiveCfg = Debug_NET481|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Debug_NET481|Any CPU.Build.0 = Debug_NET481|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Debug_NET8|Any CPU.ActiveCfg = Debug_NET8|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Debug_NET8|Any CPU.Build.0 = Debug_NET8|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Release_NET481|Any CPU.ActiveCfg = Release_NET481|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Release_NET481|Any CPU.Build.0 = Release_NET481|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Release_NET8|Any CPU.ActiveCfg = Release_NET8|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Release_NET8|Any CPU.Build.0 = Release_NET8|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A46BCB50-782B-4946-9620-F90DE462CC30}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1562,6 +1576,7 @@ Global
{CD69985E-7030-9C55-F7CF-0E4D323FED25} = {4F4FBF3C-61E6-41C8-97B0-05A1AA806BA9}
{CB713D02-195C-1E16-FB21-61ABC603D726} = {4F4FBF3C-61E6-41C8-97B0-05A1AA806BA9}
{3451F54A-A0CE-704D-194A-2769C953B0A9} = {4F4FBF3C-61E6-41C8-97B0-05A1AA806BA9}
+ {A46BCB50-782B-4946-9620-F90DE462CC30} = {4F4FBF3C-61E6-41C8-97B0-05A1AA806BA9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B18E6094-5F8C-4A40-ABCC-147C4EB191A0}
@@ -1612,6 +1627,7 @@ Global
Shared\Shared.projitems*{922bd855-deed-44e2-ba08-71dd92df1f2d}*SharedItemsImports = 5
Shared\Shared.projitems*{a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890}*SharedItemsImports = 5
Shared\Shared.projitems*{a377c035-e10f-41f0-b6c7-0d0bcb60d4b9}*SharedItemsImports = 5
+ Shared\Shared.projitems*{a46bcb50-782b-4946-9620-f90de462cc30}*SharedItemsImports = 5
Shared\Shared.projitems*{a6b95578-7844-480b-8051-056b4949e446}*SharedItemsImports = 5
Shared\Shared.projitems*{ac2530de-ed8e-431d-9cb3-f868193331de}*SharedItemsImports = 5
Shared\Shared.projitems*{acc4a188-b29c-4a1d-88f5-9e2909de7b1b}*SharedItemsImports = 5
diff --git a/Samples/Platform SDK/ResourceProviderSample/App.config b/Samples/Platform SDK/ResourceProviderSample/App.config
new file mode 100644
index 0000000..d4c108f
--- /dev/null
+++ b/Samples/Platform SDK/ResourceProviderSample/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/Samples/Platform SDK/ResourceProviderSample/Certificates/ResourceProviderSample.exe.cert b/Samples/Platform SDK/ResourceProviderSample/Certificates/ResourceProviderSample.exe.cert
new file mode 100644
index 0000000..b9a1fc9
--- /dev/null
+++ b/Samples/Platform SDK/ResourceProviderSample/Certificates/ResourceProviderSample.exe.cert
@@ -0,0 +1,5 @@
+
+ Genetec
+ Demo Certificate for SDK Development only
+ KxsD11z743Hf5Gq9mv3+5ekxzemlCiUXkTFY5ba1NOGcLCmGstt2n0zYE9NsNimv
+
diff --git a/Samples/Platform SDK/ResourceProviderSample/Program.cs b/Samples/Platform SDK/ResourceProviderSample/Program.cs
new file mode 100644
index 0000000..d1cd3d6
--- /dev/null
+++ b/Samples/Platform SDK/ResourceProviderSample/Program.cs
@@ -0,0 +1,44 @@
+// Copyright 2025 Genetec Inc.
+// Licensed under the Apache License, Version 2.0
+
+using System;
+using System.Linq;
+using Genetec.Dap.CodeSamples;
+using Genetec.Sdk;
+using Genetec.Sdk.Helpers;
+
+SdkResolver.Initialize();
+
+RunSample();
+
+Console.Write("Press any key to exit...");
+Console.ReadKey(true);
+
+void RunSample()
+{
+ Console.WriteLine("Using ResourceProvider.GetStringFromEnum to get localized names from SDK enums.\n");
+ Console.WriteLine("The following enums have ResourceReference attributes and support localized string lookup:\n");
+
+ PrintEnum("EntityType");
+ PrintEnum("RoleType");
+ PrintEnum("CredentialState");
+ PrintEnum("StreamingType");
+ PrintEnum("DeviceReaderEncryptionStatus");
+}
+
+static void PrintEnum(string enumName) where TEnum : struct, IConvertible
+{
+ Console.WriteLine($"--- {enumName} ---");
+ Console.WriteLine($"{"Value",-35} | {"Localized Name"}");
+ Console.WriteLine(new string('-', 60));
+
+ foreach (TEnum value in Enum.GetValues(typeof(TEnum)).OfType().OrderBy(v => v.ToString()))
+ {
+ string localizedName = ResourceProvider.GetStringFromEnum(value);
+ Console.WriteLine(string.IsNullOrEmpty(localizedName)
+ ? $"{value,-35} | (empty)"
+ : $"{value,-35} | {localizedName}");
+ }
+
+ Console.WriteLine();
+}
diff --git a/Samples/Platform SDK/ResourceProviderSample/ResourceProviderSample.csproj b/Samples/Platform SDK/ResourceProviderSample/ResourceProviderSample.csproj
new file mode 100644
index 0000000..3121dd0
--- /dev/null
+++ b/Samples/Platform SDK/ResourceProviderSample/ResourceProviderSample.csproj
@@ -0,0 +1,141 @@
+
+
+
+
+ net481
+
+
+ net8.0-windows;net481
+
+ net8.0-windows
+ net481
+ Debug;Release;Debug_NET481;Debug_NET8;Release_NET481;Release_NET8
+ Genetec.Dap.CodeSamples
+ ResourceProviderSample
+ Sample project
+ Genetec Inc.
+ Copyright © Genetec Inc. 2024
+ Exe
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ 12
+
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ 12
+
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug_NET8\
+ DEBUG;TRACE
+ prompt
+ 4
+ 12
+
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release_NET8\
+ TRACE
+ prompt
+ 4
+ 12
+
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug_NET481\
+ DEBUG;TRACE
+ prompt
+ 4
+ 12
+
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release_NET481\
+ TRACE
+ prompt
+ 4
+ 12
+
+
+
+
+ $(GSC_SDK)\Genetec.Sdk.dll
+ False
+
+
+
+
+
+
+
+
+ $(GSC_SDK_CORE)\Genetec.Sdk.dll
+ False
+
+
+
+
+
+
+
+
+
+ $(OutputPath)Certificates
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Samples/Shared/SdkResolverNetCoreApp.cs b/Samples/Shared/SdkResolverNetCoreApp.cs
index a7670e8..6c217bf 100644
--- a/Samples/Shared/SdkResolverNetCoreApp.cs
+++ b/Samples/Shared/SdkResolverNetCoreApp.cs
@@ -37,7 +37,7 @@ private static Assembly OnAssemblyResolve(AssemblyLoadContext context, AssemblyN
{
string key = assemblyName.FullName ?? assemblyName.Name;
- if (assemblyName.Name.EndsWith(".resources") || assemblyName.Name.EndsWith(".xmlserializers"))
+ if (assemblyName.Name.EndsWith(".xmlserializers"))
{
return null;
}
@@ -81,6 +81,11 @@ private static Assembly LoadAssembly(AssemblyLoadContext context, AssemblyName a
private static IEnumerable GetAssemblyPaths(string probingPath, AssemblyName assemblyName)
{
+ if (assemblyName.CultureInfo != null && !string.IsNullOrEmpty(assemblyName.CultureInfo.Name))
+ {
+ yield return Path.Combine(probingPath, assemblyName.CultureInfo.Name, $"{assemblyName.Name}.dll");
+ }
+
yield return Path.Combine(probingPath, $"{assemblyName.Name}.dll");
yield return Path.Combine(probingPath, $"{assemblyName.Name}.exe");
diff --git a/Samples/Shared/SdkResolverNetFramework.cs b/Samples/Shared/SdkResolverNetFramework.cs
index 517922c..edbccf9 100644
--- a/Samples/Shared/SdkResolverNetFramework.cs
+++ b/Samples/Shared/SdkResolverNetFramework.cs
@@ -21,6 +21,11 @@ public static class SdkResolver
public static void Initialize()
{
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
+
+ if (Directory.Exists(s_probingPath))
+ {
+ Environment.CurrentDirectory = s_probingPath;
+ }
}
private static string GetProbingPath()
@@ -67,7 +72,7 @@ private static string GetProbingPath()
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
{
- if (args.Name.EndsWith(".resources") || args.Name.EndsWith(".xmlserializers"))
+ if (args.Name.EndsWith(".xmlserializers"))
{
return null;
}
@@ -98,6 +103,12 @@ private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
private static IEnumerable GetAssemblyPaths(string probingPath, string assemblyName)
{
var parsedAssemblyName = new AssemblyName(assemblyName);
+
+ if (parsedAssemblyName.CultureInfo != null && !string.IsNullOrEmpty(parsedAssemblyName.CultureInfo.Name))
+ {
+ yield return Path.Combine(probingPath, parsedAssemblyName.CultureInfo.Name, $"{parsedAssemblyName.Name}.dll");
+ }
+
yield return Path.Combine(probingPath, $"{parsedAssemblyName.Name}.dll");
yield return Path.Combine(probingPath, $"{parsedAssemblyName.Name}.exe");