Integrating Honeygain SDK with Windows .NET/C# applications
This guide will go through the process of integrating and using Honeygain SDK in your .NET/C# desktop application.
Don't forget to generate your Honeygain SDK API Key and download the SDK from the Developers dashboard first.
Integration
On Windows, the SDK service is provided for x64, x86, and arm64 architectures. The SDK service dynamic-link libraries x64\bin\hgsdk.dll, x86\bin\hgsdk.dll, and arm64\bin\hgsdk.dll should be accessible to your application's executable. It is recommended to place them in the same directory tree as your application's executable. If you need to support only one architecture, you can use only one of the provided libraries.
You cannot mix architectures (e.g., an x64 process cannot load an arm64 DLL).
With Visual Studio
If you are using Visual Studio, you can automatically place the SDK service dynamic-link libraries in the output directory using a post-build event:
- Right-click on your project in Solution Explorer and select Properties.
- In the properties window, go to Build Events on the left sidebar.
- In the Post-build event command line field add the following command:
mkdir "$(TargetDir)\x86"
mkdir "$(TargetDir)\x64"
mkdir "$(TargetDir)\arm64"
copy /Y "<path to>\x86\bin\hgsdk.dll" "$(TargetDir)\x86\hgsdk.dll"
copy /Y "<path to>\x64\bin\hgsdk.dll" "$(TargetDir)\x64\hgsdk.dll"
copy /Y "<path to>\arm64\bin\hgsdk.dll" "$(TargetDir)\arm64\hgsdk.dll" - Replace
<path to>with the path to the directory where the SDK service dynamic-link libraries are located.
SDK service functions can be called from managed code using Platform Invoke (P/Invoke) functionality.
In order to call the SDK service functions, add the following class to your application's source code:
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
static class Hgsdk
{
private const string File = "hgsdk.dll";
static Hgsdk()
{
var root = AppDomain.CurrentDomain.BaseDirectory;
string arch;
if (RuntimeInformation.ProcessArchitecture == Architecture.X86)
arch = "x86";
else if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
arch = "x64";
else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
arch = "arm64";
else
throw new PlatformNotSupportedException("Unsupported architecture");
string path = Path.Combine(root, arch, File);
if (LoadLibrary(path) == IntPtr.Zero)
throw new DllNotFoundException($"{path} (Win32 {Marshal.GetLastWin32Error()})");
AppDomain.CurrentDomain.ProcessExit += OnExit;
AppDomain.CurrentDomain.DomainUnload += OnExit;
}
public static void Init(string api_key)
{
if (hgsdk_init(api_key) < 0)
throw new Exception("Failed to initialize the service");
}
public static bool Start()
{
if (hgsdk_start(out var consent) < 0)
throw new Exception("Failed to start the service");
return consent;
}
public static void Stop()
{
if (hgsdk_stop() < 0)
throw new Exception("Failed to stop the service");
}
public static string Identify()
{
UIntPtr size = UIntPtr.Zero;
if (hgsdk_identify(null, ref size) < 0)
throw new Exception("Failed to get size of identity data");
var data = new StringBuilder((int)size);
size = (UIntPtr)data.Capacity;
if (hgsdk_identify(data, ref size) < 0)
throw new Exception("Failed to get identity data");
return data.ToString();
}
public static bool IsRunning()
{
if (hgsdk_is_running(out var running) < 0)
throw new Exception("Failed to check if the service is running");
return running;
}
public static void OptIn()
{
if (hgsdk_opt_in() < 0)
throw new Exception("Failed to opt in user");
}
public static void OptOut()
{
if (hgsdk_opt_out() < 0)
throw new Exception("Failed to opt out user");
}
public static bool IsOptedIn()
{
if (hgsdk_is_opted_in(out var consent) < 0)
throw new Exception("Failed to check if user is opted in");
return consent;
}
public static bool RequestConsent()
{
if (hgsdk_request_consent(out var consent) < 0)
throw new Exception("Failed to request user consent");
return consent;
}
public static void Log(string dir)
{
if (hgsdk_log(dir) < 0)
throw new Exception("Failed to enable logging for the service");
}
public static void Mute()
{
if (hgsdk_mute() < 0)
throw new Exception("Failed to disable logging for the service");
}
private static void OnExit(object sender, EventArgs e)
{
try
{
Stop();
}
catch { }
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern IntPtr LoadLibrary(string file);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_init(string api_key);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_start(out bool consent);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_stop();
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_identify([MarshalAs(UnmanagedType.LPStr)] StringBuilder data, ref UIntPtr size);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_is_running(out bool running);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_opt_in();
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_opt_out();
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_is_opted_in(out bool consent);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_request_consent(out bool consent);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_log(string dir);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int hgsdk_mute();
}
Full working example can be found in the samples/dotnet directory of the downloaded Honeygain SDK.
Usage
In the above example, the class calls .Stop() when the application is closing. It is recommended to do this in your application as well so the SDK service shuts down cleanly.
Note that .Start() and .Stop() are non-blocking. Internally, starting and stopping the SDK service are asynchronous, so there may be a slight delay before the action takes effect.
Initializing SDK service
To initialize the SDK service, call .Init():
Hgsdk.Init("your-api-key");
The parameter is your Honeygain SDK API Key. If the service is already initialized and a different API key is provided, the old instance is terminated and a new one is initialized. If the service is already initialized and the same API key is provided, the call effectively does nothing.
It is required to call this function before any other SDK service function.
Starting SDK service
To start the SDK service, call .Start():
bool consent = Hgsdk.Start();
It checks whether explicit user consent was given previously. The current consent state is returned by the method. If consent was given previously, the SDK service starts. If not, the SDK service does not start and the method returns false.
If the SDK service is already running, the call effectively does nothing.
Stopping SDK service
To stop the SDK service, call .Stop():
Hgsdk.Stop();
Stops the SDK service if it is running. If the SDK service is not running, this method does nothing.
Identifying SDK service
To retrieve the SDK service identifier string, call .Identify():
string identifier = Hgsdk.Identify();
This is an immediate operation and returns an opaque string that uniquely identifies the running SDK service.
Verifying SDK service state
To verify whether the SDK service is running, call .IsRunning():
bool running = Hgsdk.IsRunning();
This is an immediate operation and reports SDK service state at the current time without blocking.
Providing user consent
To provide user consent, call .OptIn():
Hgsdk.OptIn();
Records that user consent was given and allows the SDK service to start. Subsequent calls to .Start() are allowed to start the SDK service.
Revoking user consent
To revoke user consent, call .OptOut():
Hgsdk.OptOut();
Records that user consent was revoked. The SDK service stops if it is running. Subsequent calls to .Start() are not allowed to start the SDK service.
Verifying user consent state
To verify whether user consent was given, call .IsOptedIn():
bool consent = Hgsdk.IsOptedIn();
Returns the stored consent state.
Requesting user consent
To request user consent, call .RequestConsent():
bool consent = Hgsdk.RequestConsent();
Displays the default user agreement window.
If the user accepts the agreement, consent is stored and subsequent calls to .Start() are allowed to start the SDK service.
If the user declines or closes the window, subsequent calls to .Start() are not allowed unless consent was previously given.
This function is blocking and returns only after the user accepts or declines.
Enable logging
To enable logging, call .Log():
Hgsdk.Log("C:\\path\\to\\log\\directory");
Enables logging for the SDK service. Log files are created in the specified directory. If the directory is not specified, log files will be created in the current working directory of your application. Logs are also written to standard output.
Disable logging
To disable logging, call .Mute():
Hgsdk.Mute();
Disables logging for the SDK service. Any log file is closed and writing to standard output is stopped.
Function reference
hgsdk_start() and hgsdk_stop() are non-blocking. Internally, starting and stopping the Honeygain SDK service are asynchronous operations, so there can be a slight delay before the action takes effect.
hgsdk_init
Initialize the SDK service.
int32_t hgsdk_init(const char *api_key);
Parameters
| Name | Type | Description |
|---|---|---|
api_key | const char* | Your API key provided by Honeygain SDK. |
Returns
0 on success; otherwise a negative error code.
Remarks
- If the service is already initialized and a different API key is provided, the old instance is terminated and a new one is initialized.
- If the service is already initialized and the same API key is provided, the function call effectively does nothing.
api_keyis copied by the SDK; its memory does not need to remain valid after the call returns.
It is required to call this function before any other SDK service function.
hgsdk_start
Start the SDK service.
int32_t hgsdk_start(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: consent state. Set to 1 if user consent was previously given, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Checks whether explicit user consent was given before. The current consent state is returned via
*state. - If consent was previously given, the SDK service starts. If not, the service does not start and
*stateis set to0. - If the service is already running, the function call effectively does nothing.
It is recommended to obtain user consent before starting the SDK service.
hgsdk_stop
Stop the SDK service.
int32_t hgsdk_stop(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Stops the SDK service if it is running.
- If the service is not running, this function does nothing.
It is recommended to stop the SDK service before closing your application so the service shuts down cleanly.
hgsdk_identify
Get the SDK service identifier.
int32_t hgsdk_identify(char *data, size_t *size);
Parameters
| Name | Type | Description |
|---|---|---|
data | char* | Buffer to receive a NUL-terminated ASCII string. If not NULL, the function writes up to *size bytes and sets *size to the number of bytes actually written. |
size | size_t* | In/out. If data is NULL, on return *size is set to the number of bytes required to store the full NUL-terminated string. If data is not NULL, on return *size is set to the number of bytes actually written. |
Returns
0 on success; otherwise a negative error code.
Remarks
- The identifier is stable across runs on the device.
- Use the two-call pattern to retrieve the full value: call with
data == NULLto get required size (in bytes), allocate that many bytes, then call again withdataandsize. - The returned string is NUL-terminated and plain ASCII.
- If the provided buffer (
data/*size) is smaller than required, the string is truncated to fit (ensuring NUL termination when*size > 0),*sizeis set to the number of bytes actually written, and the function returns0.
hgsdk_is_running
Check if the SDK service is running.
int32_t hgsdk_is_running(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: set to 1 if the service is running, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
hgsdk_opt_in
Provide user consent.
int32_t hgsdk_opt_in(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Persists that user consent was given and informs the SDK service that it may start.
- Subsequent calls to
hgsdk_start()will be allowed to start the service.
hgsdk_opt_out
Revoke user consent.
int32_t hgsdk_opt_out(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Persists that user consent was revoked and informs the SDK service that it should stop if running.
- Subsequent calls to
hgsdk_start()will not be allowed to start the service.
hgsdk_is_opted_in
Check whether user consent was given.
int32_t hgsdk_is_opted_in(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: set to 1 if consent was given, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Returns the stored consent state via
*state.
hgsdk_request_consent
Display the default user agreement window and capture consent.
int32_t hgsdk_request_consent(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: set to 1 if the user accepts, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Shows the default user agreement UI.
- If the user accepts, consent is stored and the SDK service may start. Subsequent
hgsdk_start()calls are allowed. - If the user declines or closes the window, subsequent
hgsdk_start()calls are not allowed unless consent was previously given.
This function is blocking and returns only after the user accepts or declines the agreement.
hgsdk_log
Enable logging for the SDK service.
int32_t hgsdk_log(const char *dir);
Parameters
| Name | Type | Description |
|---|---|---|
dir | const char* | Directory where log files will be stored. If NULL or empty, logs are created in the current working directory. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Enables logging and writes logs to the specified directory (created if it does not exist).
- Logs are also written to standard output.
- Subsequent calls to
hgsdk_log()create a new log file in the specified directory.
hgsdk_mute
Disable logging for the SDK service.
int32_t hgsdk_mute(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Disables logging: closes any open log file and stops writing to standard output.
- Existing log files are not deleted and can be inspected for debugging.