Table of Contents

Class WindowsVpnPluginDevice

Namespace
VpnHood.Core.Client.Devices.WindowsVpnPlugin
Assembly
VpnHood.Core.Client.Devices.WindowsVpnPlugin.dll

Represents the app's side of the Windows VPN plug-in: Windows owns the virtual interface and launches the package's VPN host when this device connects its VpnPlugInProfile; the app reaches that host through the package's app service, which Windows runs in it.

public sealed class WindowsVpnPluginDevice : IDevice, IDisposable
Inheritance
WindowsVpnPluginDevice
Implements
Inherited Members

Constructors

WindowsVpnPluginDevice(string)

Initializes a new instance of the WindowsVpnPluginDevice class.

public WindowsVpnPluginDevice(string profileName)

Parameters

profileName string

The profile's name in Windows' VPN settings and quick settings: the app's name.

Exceptions

ArgumentException

profileName is empty.

ArgumentNullException

profileName is null.

InvalidOperationException

The process does not run from the package.

Fields

PluginConnectTimeout

The VPN plug-in's wait for its session at a connect (WindowsVpnPluginService), which a dial outlasts: 60 seconds.

public static readonly TimeSpan PluginConnectTimeout

Field Value

TimeSpan

Properties

IsAlwaysOnSupported

Gets a value indicating whether the app can keep the VPN always on itself, which its always-on setting then turns on, as a desktop's service that starts at boot does; false where the system does it, as on Android, whose setting the app only opens.

public bool IsAlwaysOnSupported { get; }

Property Value

bool

Remarks

Not the app's: nothing of the package runs at boot, and the app's window, closed, waits only while the VPN is up. Nor Windows' own Always On (the profile's AlwaysOn, and the person's "Connect automatically"): it would start the VPN host without the app, which Windows freezes between VPN events while no app holds it.

IsBindProcessToVpnSupported

Gets a value indicating whether BindProcessToVpn(bool) works on the device.

public bool IsBindProcessToVpnSupported { get; }

Property Value

bool

IsExcludeAppsSupported

Gets a value indicating whether the device can keep chosen apps out of the tunnel.

public bool IsExcludeAppsSupported { get; }

Property Value

bool

IsIncludeAppsSupported

Gets a value indicating whether the device can let only chosen apps into the tunnel.

public bool IsIncludeAppsSupported { get; }

Property Value

bool

IsQuicSupported

Gets a value indicating whether the device can make QUIC connections.

public bool IsQuicSupported { get; }

Property Value

bool

IsTv

Gets a value indicating whether the device is a TV.

public bool IsTv { get; }

Property Value

bool

IsWaitingForVpnPermission

Gets a value indicating whether RequestVpnService(IUiContext?, TimeSpan, CancellationToken) waits on the OS's prompt for the person's yes, so a UI elsewhere, as a browser driving a TV, can say where the connection waits.

public bool IsWaitingForVpnPermission { get; }

Property Value

bool

Remarks

RequestVpnService(IUiContext?, TimeSpan, CancellationToken) only makes the profile, with no prompt.

KillSwitch

Gets the kill switch's block, where the device has one, as a desktop's service; otherwise, null. The device holds it, as it outlives each connection's VPN service, whose host controls the same block through a controller of its own.

public IVpnKillSwitch? KillSwitch { get; }

Property Value

IVpnKillSwitch

Remarks

None: the sandbox cannot reach the Windows Filtering Platform, and Windows' own lockdown is set only by MDM.

MemInfo

Gets the device's memory as the platform reports it now, or null where it is not known; a desktop's comes from the .NET garbage collector's view.

public DeviceMemInfo MemInfo { get; }

Property Value

DeviceMemInfo

OsInfo

Gets a description of the device and its OS, as Google: Pixel 8, Android: 16.

public string OsInfo { get; }

Property Value

string

UserAgentInfo

Gets the parts of a browser's user agent on the device, which the app builds its own from.

public DeviceUserAgentInfo UserAgentInfo { get; }

Property Value

DeviceUserAgentInfo

Remarks

As Chrome says it here, whose NT version reads 10.0 on Windows 11 too.

VpnServiceConfigFolder

Gets the folder of the VPN service's own files: its options, status and log, and the split filters the app publishes for it, meant to stay on this device, out of backups and transfers to a new device.

public string VpnServiceConfigFolder { get; }

Property Value

string

Remarks

Where the device can, the folder is kept out of the OS's backups: Android's is its folder outside them, and on iOS a failure to exclude it is only logged. A desktop's is an ordinary folder.

Exceptions

InvalidOperationException

Android gives no folder outside its backups.

VpnServiceDataFolder

Gets the folder of what the app and the VPN service share that is the person's own, as the proxies they added, meant to travel with a backup where the OS backs it up; tvOS keeps it among its caches.

public string VpnServiceDataFolder { get; }

Property Value

string

Remarks

It is the same folder as the config folder.

Methods

BindProcessToVpn(bool)

Binds the app's own connections to the system's default network, which is the VPN while one is connected, or, with false, to a network outside the VPN: on Android, the first of Ethernet, Wi-Fi, USB, satellite, Bluetooth and cellular.

public void BindProcessToVpn(bool value)

Parameters

value bool

true for the system's default network; false for a network outside the VPN.

Remarks

true throws NotSupportedException; false does nothing.

Exceptions

NotSupportedException

The device does not support it (IsBindProcessToVpnSupported).

Exception

Android found no network outside the VPN.

CreateMessageClient()

Creates a client of the VPN service's messages, through which the app commands it.

public IMessageClient CreateMessageClient()

Returns

IMessageClient

The client.

Remarks

It is the package's app service's client.

Dispose()

Does nothing: Windows owns the VPN host and the connection's lifetime.

public void Dispose()

GetInstalledApps(CancellationToken)

Gets the installed apps a split by app can pick from, each with its name and icon.

public Task<IReadOnlyList<DeviceAppInfo>> GetInstalledApps(CancellationToken cancellationToken)

Parameters

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task<IReadOnlyList<DeviceAppInfo>>

A task whose result is the apps: on Android, by name; a Windows debug build gives test entries.

Remarks

The VPN plug-in cannot split by app, so it always throws NotSupportedException.

Exceptions

NotSupportedException

The device cannot split by app.

InvalidOperationException

Android's package manager or an app's resources are not available.

Exception

Android could not encode an app's icon.

OperationCanceledException

cancellationToken was canceled.

RequestVpnService(IUiContext?, TimeSpan, CancellationToken)

Prepares the device to run the app's VPN service: on Android, it asks for the person's consent with the OS's prompt where the OS requires it now; on the Windows VPN plug-in, it prepares the VPN profile; elsewhere it may do nothing, as iOS configures the VPN when it starts.

public Task RequestVpnService(IUiContext? uiContext, TimeSpan timeout, CancellationToken cancellationToken)

Parameters

uiContext IUiContext

The UI to show a prompt in, or null; on Android, one given must be Android's own, and one is needed where the OS must ask.

timeout TimeSpan

How long to wait for the person's answer, where the device waits for one, as Android does.

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task

A task that completes once the device is prepared.

Remarks

It makes the package's VPN profile where Windows has none, in place of one of its name that is not this package's or has no server, which it disconnects and removes first; there is no prompt.

Exceptions

UserCanceledException

The person refused, on Android.

Exception

Android must ask, and no UI was given.

InvalidCastException

The UI given is not Android's own, on Android.

ArgumentOutOfRangeException

timeout is negative, other than -1 ms, or too long, on Android.

TimeoutException

The person did not answer in time, or the wait was canceled, on Android; or the Windows VPN plug-in's profile did not disconnect in time.

InvalidOperationException

The Windows VPN plug-in's profile could not be prepared.

OperationCanceledException

cancellationToken was canceled.

StartVpnService(CancellationToken)

Starts the VPN service, which then connects as its options in the config folder say. The task completes once the start is under way, not when the VPN is up; the app's service manager waits for that.

public Task StartVpnService(CancellationToken cancellationToken)

Parameters

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task

A task that represents the asynchronous operation.

Remarks

iOS fails it with an NSErrorException of its own.

Exceptions

VpnServiceException

Android could not start the service.

InvalidOperationException

A desktop's VPN host or the Windows VPN plug-in's profile is missing or failed.

ObjectDisposedException

A desktop's VPN host process was disposed.

TimeoutException

The Windows VPN plug-in did not start in time.

Win32Exception

Windows refused the VPN host's process.

OperationCanceledException

cancellationToken was canceled.

TryGetLiveProfiles()

Gets the package's profiles Windows holds other than disconnected: the app's client asks before it opens the app service, and the VPN plug-in before it waits for a connect.

public static Task<VpnPlugInProfile[]?> TryGetLiveProfiles()

Returns

Task<VpnPlugInProfile[]>

A task whose result is the profiles, or null where Windows does not say, which it logs.