Add program for portable Windows builds to register a per-user protocol handler

Replaces the old play_community_level.bat Batch script that was bundled with portable
This commit is contained in:
ROllerozxa 2026-06-21 16:13:53 +02:00
commit 7f87a48538
7 changed files with 149 additions and 76 deletions

View file

@ -321,6 +321,15 @@ if(NOT APPLE)
string(APPEND CMAKE_EXE_LINKER_FLAGS_RELEASE "-Wl,-s ")
endif()
# Register protocol handler util on Windows
# -----------------------------------------
if(WIN32)
add_executable(register-protocol-handler
packaging/register-protocol-handler/main.c
packaging/register-protocol-handler/windows.rc)
endif()
# Installation
# ------------

View file

@ -1,75 +0,0 @@
@echo off
setlocal enabledelayedexpansion
set domain=null
set level=null
goto main
:select_domain
:principia_web
set domain=principia-web.se
goto select_level
:archive_principia_web
set domain=archive.principia-web.se
goto select_level
:custom
cls
echo.
echo Enter the domain of the community site you want to use.
echo (Example: grejer.voxelmanip.se, NO "https://" or trailing slashes!)
echo.
set /p domain=^>
if "!domain!" NEQ "" goto select_level
goto custom
:select_level
cls
echo.
echo Enter the numeric ID of the level you want to play.
echo.
echo (To find a level's ID, see the URL "/level/<ID>", or
echo the "Level ID: <ID>" below the level's thumbnail.)
echo.
set /p level=^>
if "!level!" NEQ "" goto run_principia
goto select_level
:run_principia
REM | See https://principia-web.se/wiki/Principia_Protocol for info about the protocol
start principia.exe principia://!domain!/play/lvl/db/!level! > nul
goto select_level
:main
echo.
echo This is a helper script to allow playing levels with a portable version of
echo Principia without needing to install registry keys.
echo.
echo For more info about the portable Windows build of Principia see:
echo https://principia-web.se/wiki/Windows_Portable
echo.
echo Select a community site domain:
echo 1. principia-web.se
echo 2. archive.principia-web.se
echo 3. Custom domain
echo.
:main_loop
choice /c 123 /n
if %ERRORLEVEL% == 1 goto principia_web
if %ERRORLEVEL% == 2 goto archive_principia_web
if %ERRORLEVEL% == 3 goto custom
goto main_loop

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,83 @@
#include <wchar.h>
#include <windows.h>
static int GetExeDirW(wchar_t *outDir, DWORD size) {
DWORD len = GetModuleFileNameW(NULL, outDir, size);
if (len == 0 || len == size) return 0;
for (DWORD i = len; i > 0; --i) {
if (outDir[i] == L'\\') {
outDir[i + 1] = 0;
return 1;
}
}
return 0;
}
static int WriteRegistry() {
wchar_t exeDir[MAX_PATH];
wchar_t principiaPath[MAX_PATH * 2];
if (!GetExeDirW(exeDir, MAX_PATH))
return 0;
swprintf(principiaPath, MAX_PATH * 2, L"\"%sprincipia.exe\" %%1", exeDir);
HKEY hKey;
LONG res = RegCreateKeyExW(
HKEY_CURRENT_USER,
L"Software\\Classes\\principia",
0,
NULL,
0,
KEY_WRITE,
NULL,
&hKey,
NULL
);
if (res != ERROR_SUCCESS)
return 0;
const wchar_t *protocol = L"URL:Principia";
const wchar_t *empty = L"";
RegSetValueExW(hKey, NULL, 0, REG_SZ, (const BYTE*)protocol,
(DWORD)((wcslen(protocol) + 1) * sizeof(wchar_t)));
RegSetValueExW(hKey, L"URL Protocol", 0, REG_SZ, (const BYTE*)empty,
(DWORD)sizeof(wchar_t));
HKEY hSub;
RegCreateKeyExW(hKey, L"shell\\open\\command",
0, NULL, 0, KEY_WRITE, NULL, &hSub, NULL);
RegSetValueExW(hSub, NULL, 0, REG_SZ,
(const BYTE*)principiaPath,
(DWORD)((wcslen(principiaPath) + 1) * sizeof(wchar_t)));
RegCloseKey(hSub);
RegCloseKey(hKey);
return 1;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
int ret = MessageBoxW(
NULL,
L"Register a principia:// protocol handler for this user? This will make changes in the Windows Registry.",
L"Register Principia Protocol Handler",
MB_YESNO | MB_ICONQUESTION
);
if (ret == IDYES) {
if (WriteRegistry())
MessageBoxW(NULL, L"Protocol registered.", L"Success", MB_OK | MB_ICONINFORMATION);
else
MessageBoxW(NULL, L"Failed to register protocol.", L"Error", MB_OK | MB_ICONERROR);
}
return 0;
}

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 and Windows 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
</application>
</compatibility>
</assembly>

View file

@ -0,0 +1,33 @@
#include <windows.h>
1 ICON "icon.ico"
1 24 "windows.manifest"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "ROllerozxa"
VALUE "FileDescription", "Register protocol handler for Principia"
VALUE "FileVersion", "1.0.0"
VALUE "InternalName", "register-protocol-handler"
VALUE "LegalCopyright", "Copyright (c) 2026 ROllerozxa"
VALUE "OriginalFilename", "register-protocol-handler.exe"
VALUE "ProductName", "Register Protocol Handler"
VALUE "ProductVersion", "1.0.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View file

@ -4,7 +4,7 @@
touch release/portable.txt
cp ../packaging/play_community_level.bat release/
cp register-protocol-handler.exe release/
cp -r ../data/ release/