diff --git a/README.md b/README.md index 268ac80..55ae7eb 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,65 @@ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) -RustDesk provides several ways to configure the client application. One way that is supported for the Windows client is to encode the settings in the filename. This tool provides a way to easily create such a filename without having to purchase the Pro version of the tool. \ No newline at end of file +RustDesk provides several ways to configure the client application. One way that is supported for the Windows client is to encode the settings in the filename. This tool provides a way to easily create such a filename without having to purchase the Pro version of the tool. + +## Usage + +1. Open `index.html` in any modern browser (or visit the hosted page). +2. Fill in the fields you need: + - **ID Server** – your `hbbs` host or IP (required, e.g. `hbbs.example.com`). + - **Relay Server** – optional; RustDesk usually infers it. + - **API Server** – Pro only (e.g. `https://hbbs.example.com`). + - **Key** – the public key found in `id_ed25519.pub` on your server. +3. The generated file name (e.g. `rustdesk----.exe`) updates automatically. +4. Click **Copy**, then rename your `rustdesk.exe` to the copied file name. On launch the + client reads the encoded settings from its own file name. + +Only the fields you fill in are included in the encoded config. Everything runs locally in +your browser — no data is sent anywhere. + +### Two ways to apply the config + +RustDesk can read this config in two different ways, and they don't behave identically: + +| | File name method (rename `.exe`) | `--config` import | +| --- | --- | --- | +| How | Rename `rustdesk.exe` to the generated name | `rustdesk.exe --config ""` | +| `host` / `key` / `api` | Read **at launch** from the file name | Read and **saved** to settings | +| `relay` | Ignored — auto-deduced from the ID Server | **Saved** to settings | +| Shows in Settings → Network | No (applied at runtime only) | Yes (values are persisted) | +| Requirements | None | RustDesk installed + run as Administrator | + +If you fill in an **API Server** (or want the values to appear/persist in +Settings → Network), use the `--config` command the page generates: + +```powershell +rustdesk.exe --config "" +``` + +This is verified against RustDesk's source (`src/core_main.rs`), where `--config` writes +`custom-rendezvous-server`, `api-server`, `relay-server` and `key` into the stored options. +With the file name method, the API server is used at runtime but does **not** show up in the +Network settings dialog, and the Relay field shows the ID Server because RustDesk deduces it. + +### Download & rename in one step + +The page also detects the latest RustDesk release (via the GitHub API) and provides: + +- a direct **download link** to the newest Windows x64 build, and +- a ready-to-run **PowerShell command** that downloads the client and saves it with the + generated file name in one step: + +```powershell +Invoke-WebRequest -Uri "https://github.com/rustdesk/rustdesk/releases/download//rustdesk--x86_64.exe" -OutFile "rustdesk----.exe" +``` + +Because browsers can't rename a cross-origin download, the PowerShell command is the +reliable way to get the binary already named correctly. Run it from the folder where you +want the file. + +## How it works + +The settings are assembled into a small JSON object, encoded as URL-safe Base64, reversed, +and wrapped as `rustdesk----.exe`, matching RustDesk's +[file-name configuration format](https://rustdesk.com/docs/en/self-host/client-configuration/). \ No newline at end of file diff --git a/index.html b/index.html index 2290012..efffaa3 100644 --- a/index.html +++ b/index.html @@ -5,91 +5,649 @@ RustDesk File Name Config Generator +
+
+

RustDesk File Name Config Generator

+

+ Preconfigure your self-hosted RustDesk client by encoding the server settings into the + rustdesk.exe file name — or generate a ready-to-run + --config import command. No Pro license required. +

+
+ 100% local & private + No Pro license needed + Auto-detects latest release + Source-verified encoding +
+
-

RustDesk File Name Config Generator

-
- This form conveniently generates a file name for RustDesk.exe that contains the encoded settings defined here. More information on how this works can be found here. -
-
- - - - - +
+
+
+ 1 +
+

Enter your server

+

ID Server and Key (API & Relay optional).

+
+
+
+ 2 +
+

Copy the output

+

The --config command or the .exe file name.

+
+
+
+ 3 +
+

Apply it

+

Run --config as admin, or rename rustdesk.exe.

+
+
+
+
+
+
+

Server settings

+ +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +

+ Relay is optional (RustDesk deduces it from the ID Server). API Server is Pro only. +

+

+ Generate a configured rustdesk.exe file name (or import command) from + your server settings. + Docs. + Everything runs locally — no data is sent anywhere. +

+
- - +
+
+
+

--config import command

+ recommended +
+
+ + +
+

+ Persists ID/Relay/API/Key so they show in Settings → Network. + Run as Administrator; RustDesk must be installed. +

+
- - - +
+
+

File name

+ rename .exe +
+
+ + +
+

+ Applied at launch but not shown in Settings; relay is auto-deduced. +

+
+ Show encoded config +
{}
+
+
-

Result:

- +
+
+

Download & rename

+ latest release +
+
+ + +
+

Looking up the latest RustDesk release…

+
+
+
+
- + +
+ async function fetchLatestRelease() { + try { + const res = await fetch('https://api.github.com/repos/rustdesk/rustdesk/releases/latest'); + if (!res.ok) throw new Error('GitHub API responded ' + res.status); + const data = await res.json(); + const assets = data.assets || []; + const asset = + assets.find(a => /-x86_64\.exe$/.test(a.name) && !/sciter/i.test(a.name)) || + assets.find(a => /x86_64\.exe$/i.test(a.name)) || + assets.find(a => /\.exe$/i.test(a.name)); + if (asset) { + downloadUrl = asset.browser_download_url; + downloadLink.href = downloadUrl; + downloadLink.textContent = `download ${data.tag_name} (x64)`; + releaseInfo.textContent = `Downloads the latest client and renames it in one step. Run in your target folder.`; + } else { + releaseInfo.textContent = `Latest release ${data.tag_name}: no Windows .exe asset found — use the link above.`; + } + } catch (err) { + releaseInfo.textContent = 'Could not auto-detect the latest version — use the link above for the newest release.'; + } finally { + updatePsCommand(); + } + } + + async function copyText(text, button) { + if (!text) return; + try { + await navigator.clipboard.writeText(text); + } catch (err) { + const tmp = document.createElement('textarea'); + tmp.value = text; + document.body.appendChild(tmp); + tmp.select(); + document.execCommand('copy'); + document.body.removeChild(tmp); + } + const original = button.dataset.label || button.textContent; + button.dataset.label = original; + button.textContent = 'Copied!'; + button.classList.add('copied'); + clearTimeout(button._resetTimer); + button._resetTimer = setTimeout(() => { + button.textContent = original; + button.classList.remove('copied'); + }, 2000); + } + + function reset() { + document.getElementById('configForm').reset(); + generate(); + } + + for (const id of fields) { + inputs[id].addEventListener('input', generate); + } + copyBtn.addEventListener('click', () => copyText(resultEl.value, copyBtn)); + copyPsBtn.addEventListener('click', () => copyText(psCommand.value, copyPsBtn)); + copyConfigBtn.addEventListener('click', () => copyText(configCommand.value, copyConfigBtn)); + resetBtn.addEventListener('click', reset); + + generate(); + fetchLatestRelease(); +