Author of findings: Core analysis of the D2Bridge Framework (Beta)
Date: April 2026
-
The D2Bridge Framework core already includes native support for detection and execution as a Windows Service.
-
No changes to the project source code or the
.dprfile are required. -
The framework automatically detects when it is running as a Windows service and adapts its behavior accordingly.
In the file D2Bridge.Util.pas, the function IsRunningAsService determines whether the application is running as a Windows service by combining two conditions:
- The process is running in Windows Session 0, which is reserved exclusively for system services.
- There is no interactive desktop available, meaning the call to
OpenInputDesktopreturns an invalid handle.
If both conditions are true, the function returns TRUE, indicating that the process is executing as a Windows service.
function IsRunningAsService: Boolean;
var
SessionId: DWORD;
hDesk: THandle;
begin
Result := False;
if not ProcessIdToSessionId(GetCurrentProcessId, SessionId) then
Exit(False);
if SessionId <> 0 then
Exit(False);
hDesk := OpenInputDesktop(0, False, DESKTOP_SWITCHDESKTOP);
if hDesk <> 0 then
begin
CloseDesktop(hDesk);
Exit(False);
end;
Result := True; // Session 0 + no interactive desktop = service
end;In D2Bridge.ServerControllerBase.pas, the method CheckNeedConsole uses the result returned by IsRunningAsService.
function TD2BridgeServerControllerBase.CheckNeedConsole: boolean;
begin
result := true;
{$IFDEF MSWINDOWS}
result := not IsRunningAsService;
{$ENDIF}
result := not IsD2DockerContext;
end;When IsRunningAsService returns TRUE, the NeedConsole flag becomes FALSE. As a result, all console-related interaction is automatically skipped.
Specifically:
-
The interactive prompt for server port and server name is not displayed.
-
The status screen with counters and resource monitoring is not displayed.
-
The server starts immediately without any user interaction.
-
The internal main loop continues to run normally, but without console output, performing internal monitoring only.
When running without a console, the server reads configuration values directly from a file named Config.ini, located in the same directory as the executable file.
function TD2BridgeAPPConfig.ServerPort(ADefaultPort: Integer): Integer;
begin
Result := FFileINIConfig.ReadInteger('D2Bridge Server Config', 'Server Port', ADefaultPort);
end;
function TD2BridgeAPPConfig.ServerName(...): String;
begin
Result := FFileINIConfig.ReadString('D2Bridge Server Config', 'Server Name', ADefaultServerName);
end;Before registering the application as a service, create a file named Config.ini in the same directory as the executable with the following content:
[D2Bridge Server Config]
Server Port=8888
Server Name=YourServerName💡 Replace
8888with your desired port number andYourServerNamewith your preferred server name.
🚨 Prerequisite: Run Command Prompt (
cmd) or PowerShell as Administrator.
- Register the service:
sc create ServiceName binPath= "C:\Full\Path\Application.exe" start= auto DisplayName= "Visible Service Name"
- Start the service:
sc start ServiceName
- Stop the service:
sc stop ServiceName
- Remove the service:
sc delete ServiceName
⚠️ Important: The space afterbinPath=andstart=is strictly mandatory when usingsc.exe.
NSSM (Non-Sucking Service Manager) is a free tool that provides automatic restart on crashes and supports redirection of output to log files.
-
Download: https://nssm.cc/download
-
Install using the graphical interface:
nssm install ServiceName
-
Install via command line:
nssm install ServiceName "C:\Full\Path\Application.exe" -
Start the service:
nssm start ServiceName
-
Stop and remove the service:
nssm stop ServiceName nssm remove ServiceName confirm
-
Windows starts the service in Session 0 without an interactive desktop.
-
The executable process is launched.
-
IsRunningAsServicereturnsTRUE. -
NeedConsoleis set toFALSE. -
TD2BridgeServerConsole.Runis executed (same logic as console mode). -
The console configuration screen is skipped.
-
Server port and server name are read from
Config.ini. -
D2BridgeServerController.StartServeris executed normally. -
The HTTP/HTTPS server starts accepting connections.
-
The internal loop keeps the process alive while the server is running.
-
The
.dprfile does not require any modification. -
The
Config.inifile must exist before starting the service for the first time. If it does not exist, default values defined in the code will be used (port 8888 and the default server name). -
SSL certificate paths must be configured in the code before compilation, as there is no interactive way to configure them when running as a service.
-
Errors and crashes can be inspected using Windows Event Viewer:
eventvwr.msc$\rightarrow$ Windows Logs$\rightarrow$ Application. -
The service runs under the SYSTEM account by default. If access to network resources is required (remote databases, shared folders, etc.), configure a dedicated service account with appropriate permissions.