Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Samples/Genetec.Dap.CodeSamples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions Samples/Platform SDK/ResourceProviderSample/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8.1" />
</startup>
</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<ClientCertificate>
<CompanyName>Genetec</CompanyName>
<ApplicationName>Demo Certificate for SDK Development only</ApplicationName>
<ApplicationId>KxsD11z743Hf5Gq9mv3+5ekxzemlCiUXkTFY5ba1NOGcLCmGstt2n0zYE9NsNimv</ApplicationId>
</ClientCertificate>
44 changes: 44 additions & 0 deletions Samples/Platform SDK/ResourceProviderSample/Program.cs
Original file line number Diff line number Diff line change
@@ -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>("EntityType");
PrintEnum<RoleType>("RoleType");
PrintEnum<CredentialState>("CredentialState");
PrintEnum<StreamingType>("StreamingType");
PrintEnum<DeviceReaderEncryptionStatus>("DeviceReaderEncryptionStatus");
}

static void PrintEnum<TEnum>(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<TEnum>().OrderBy(v => v.ToString()))
{
string localizedName = ResourceProvider.GetStringFromEnum(value);
Console.WriteLine(string.IsNullOrEmpty(localizedName)
? $"{value,-35} | (empty)"
: $"{value,-35} | {localizedName}");
}

Console.WriteLine();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<!-- Base target framework - always supported -->
<TargetFrameworks>net481</TargetFrameworks>

<!-- Conditionally add .NET 8 support if Security Center 5.12.2+ SDK is detected -->
<TargetFrameworks Condition="Exists('$(GSC_SDK_CORE)')">net8.0-windows;net481</TargetFrameworks>
<!-- Framework-specific build configurations -->
<TargetFrameworks Condition="$(Configuration.EndsWith('_NET8')) AND Exists('$(GSC_SDK_CORE)')">net8.0-windows</TargetFrameworks>
<TargetFrameworks Condition="$(Configuration.EndsWith('_NET481'))">net481</TargetFrameworks>
<Configurations>Debug;Release;Debug_NET481;Debug_NET8;Release_NET481;Release_NET8</Configurations>
<RootNamespace>Genetec.Dap.CodeSamples</RootNamespace>
<AssemblyName>ResourceProviderSample</AssemblyName>
<Description>Sample project</Description>
<Company>Genetec Inc.</Company>
<Copyright>Copyright © Genetec Inc. 2024</Copyright>
<OutputType>Exe</OutputType>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>12</LangVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>12</LangVersion>
</PropertyGroup>

<!-- .NET 8 specific configurations -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug_NET8|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug_NET8\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>12</LangVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_NET8|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release_NET8\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>12</LangVersion>
</PropertyGroup>

<!-- .NET Framework 4.8.1 specific configurations -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug_NET481|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug_NET481\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>12</LangVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_NET481|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release_NET481\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>12</LangVersion>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net481'">
<Reference Include="Genetec.Sdk">
<HintPath>$(GSC_SDK)\Genetec.Sdk.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<!-- .NET 8 dependencies - only when Security Center 5.12.2+ SDK is available -->

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0-windows'">
<Reference Include="Genetec.Sdk">
<HintPath>$(GSC_SDK_CORE)\Genetec.Sdk.dll</HintPath>
<Private>False</Private>
</Reference>
<PackageReference Include="Microsoft.Windows.Compatibility" Version="8.0.8" />
<PackageReference Include="System.ServiceModel.Primitives" Version="4.10.3" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="7.0.0" />
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WPF" />
</ItemGroup>

<Target Name="CopyCertificates" AfterTargets="Build">
<PropertyGroup>
<CertOutputPath>$(OutputPath)Certificates</CertOutputPath>
</PropertyGroup>
<ItemGroup>
<Certificates Include="Certificates\*.cert" />
</ItemGroup>
<MakeDir Directories="$(CertOutputPath)" />
<Copy SourceFiles="@(Certificates)" DestinationFiles="@(Certificates->'$(CertOutputPath)\%(Filename)%(Extension)')" />
</Target>

<Import Project="..\..\Shared\Shared.projitems" Label="Shared" />


<!-- Validation and helpful error messages -->
<Target Name="ValidateSecurityCenterVersion" BeforeTargets="Build">
<Message Text="Security Center SDK Detection:" Importance="normal" />
<Message Text=" GSC_SDK (Legacy): $(GSC_SDK)" Importance="normal" />
<Message Text=" GSC_SDK_CORE (.NET 8): $(GSC_SDK_CORE)" Importance="normal" />
<Message Text=" Target Frameworks: $(TargetFrameworks)" Importance="normal" />

<Warning Condition="'$(TargetFramework)' == 'net8.0-windows' AND !Exists('$(GSC_SDK_CORE)')"
Text=".NET 8 target requires Security Center 5.12.2 or later. Please install the compatible SDK or use .NET Framework 4.8.1 instead." />

<Message Condition="!Exists('$(GSC_SDK_CORE)')"
Text="NOTE: .NET 8 support disabled - Security Center 5.12.2+ SDK not detected. Building for .NET Framework 4.8.1 only."
Importance="high" />
</Target>
</Project>
7 changes: 6 additions & 1 deletion Samples/Shared/SdkResolverNetCoreApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -81,6 +81,11 @@ private static Assembly LoadAssembly(AssemblyLoadContext context, AssemblyName a

private static IEnumerable<string> 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");

Expand Down
13 changes: 12 additions & 1 deletion Samples/Shared/SdkResolverNetFramework.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -98,6 +103,12 @@ private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
private static IEnumerable<string> 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");

Expand Down