Overview
The Launcher installer ships an optional Connector SDK (a .NET DLL) that you can import to simplify communication over the named pipe.
SDK Contents
Typed Models
For all messages exchanged with the Launcher (ConnectionConfiguration, CustomConnectorEvent).
LauncherIpcClient Client Functionality
-
Pipe creation and connection
-
Serialization and deserialization
-
Message framing
-
Error handling
-
Automatic reading of
ConnectionConfiguration -
Automatic event construction (
RemoteConnectionWindowCreated,RemoteConnectionWindowClosed,RemoteConnectionFailure,Custom)
Utility Methods
|
Method |
Description |
|---|---|
|
|
Creates an instance of |
|
|
Blocks execution until a |
|
|
Sends a custom user-session event to the |
|
|
Notifies the |
|
|
Notifies the |
|
|
Notifies the |
Example Usage (C#)
The following example demonstrates how to use the Connector SDK to communicate with the Launcher over a named pipe.
using Connectors;
using LoginEnterprise.Launcher.Connectors.Custom.Ipc.Client;
...
// create an instance of launcher client AND connects to the pipe
await using var launcherClient = await LauncherIpcClient.ConnectToLauncherAsync();
try {
// waits (blocks execution) until launcher sends the connection configurations
var config = await launcherClient.WaitForConnectionConfigurationAsync();
// send custom event
await launcherClient.SendCustomEventAsync("starting new session");
...
// starts remote connection
...
// notifies the launcher the remote window is created
await launcherClient.SendRemoteConnectionWindowCreatedAsync();
...
// after the window is closed
...
// notifies that the session is ended
await launcherClient.SendRemoteConnectionWindowClosedAsync();
}
catch (Exception e){
// notifies that something went wrong during the connection
await launcherClient.SendRemoteConnectionFailureAsync(
$"Connection failed: {e.Message}");
}
Using the Pipe Without the SDK
This section explains how to communicate with the Launcher over a named pipe without using the Connector SDK. It covers retrieving the pipe name, sending and receiving event messages, and implementing a minimal end-to-end flow.
1. Getting the Pipe Name
When the Launcher starts your connector, it exposes the pipe name through the VSI_IPC_PIPE_NAME environment variable. Your process should:
-
Read this environment variable.
-
Use the value to connect as a named pipe client.
Pseudo-code sample:
// get pipe name from env variables
pipeName = getenv("VSI_IPC_PIPE_NAME")
// use pipe name to connect to launcher
pipe = connect_to_named_pipe(pipeName)
// create write and read stream
reader = new TextReader(pipe, encoding=UTF8)
writer = new TextWriter(pipe, encoding=UTF8, autoFlush=true)
2. Event Messages (Newline-Delimited JSON)
Follow the format and structure of event messages exchanged between the Launcher and the Connector.
All messages over the pipe:
-
are UTF-8 encoded text,
-
contain a single JSON object per line, and
-
are terminated by a newline (
\n).
Both the Launcher and the connector follow the same pattern:
-
To send a message: serialize the JSON object to a string, then write it, followed by a newline.
-
To receive a message: read a full line (until
\n), then parse that line as JSON.
Pseudo-code sample:
// send message
jsonText = serialize_to_json(messageObject)
writer.write_line(jsonText) // appends '\n'
// receive message
line = reader.read_line() // reads until '\n'
messageObject = parse_json(line)
Important: Do not send multiple JSON objects on the same line, and do not rely on length prefixes. Newlines are the only framing mechanism.
3. Launcher > Connector: ConnectionConfiguration
Once your connector is connected to the pipe, the first message the Launcher sends is always a ConnectionConfiguration JSON object:
{
"sessionId": "<GUID>",
"host": "<string>",
"username": "<string>",
"password": "<string>",
"domain": "<string>",
"accountCustomFields": {
"<string>": "<string>"
},
"accountSecureFields": {
"<string>": "<string>"
}
}
Use this information to start your remote connection.
4. Connector > Launcher: CustomConnectorEvent
While handling the connection, you can report status back to the Launcher using CustomConnectorEvent messages:
{
"eventType": "<CustomConnectorEventType>",
"message": "<string>",
"processId": <int|null>
}
Where eventType is one of:
[
"Custom",
"RemoteConnectionWindowCreated",
"RemoteConnectionFailure",
"RemoteConnectionWindowClosed"
]