Skip to content

Commit 54c9d83

Browse files
committed
Release v2026.02.11
1 parent 9a5187f commit 54c9d83

8 files changed

Lines changed: 220 additions & 8 deletions

.gitignore

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ ipch/
5252
# Local diagnostic scripts (not for version control)
5353
check-all-env-vars.ps1
5454
check-mohm-setup.ps1
55-
check-mohm-network.ps1
56-
fix-mohm-config.ps1
57-
set-missing-env-vars.ps1
58-
set-queue-url.ps1
5955
*.aps
6056
*.ncb
6157
*.opensdf

DesktopShell/Forms/ShellForm.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ public Shell()
165165

166166
if (Settings.EnableTCPServer)
167167
{
168+
if (GlobalVar.IsDefaultPassPhrase)
169+
{
170+
GlobalVar.Log("### TCP server enabled but DESKTOPSHELL_PASSPHRASE is missing/using default. Remote commands are insecure.");
171+
GlobalVar.ToolTip("Security", "DESKTOPSHELL_PASSPHRASE is missing or default. Remote commands are insecure.");
172+
}
168173
GlobalVar.ServerInstance = new TCPServer();
169174
}
170175
else
@@ -203,6 +208,11 @@ private bool PopulateCombos()
203208
browserList.Clear();
204209

205210
//Populate Combinations
211+
if (!File.Exists("shortcuts.txt"))
212+
{
213+
GlobalVar.Log("### shortcuts.txt not found. No shortcut combos loaded.");
214+
return false;
215+
}
206216
using (StreamReader? sr = new("shortcuts.txt"))
207217
{
208218
while (!sr.EndOfStream)
@@ -233,6 +243,11 @@ private bool PopulateCombos()
233243
}
234244

235245
//Populate WebBrowsers
246+
if (!File.Exists("webbrowsers.txt"))
247+
{
248+
GlobalVar.Log("### webbrowsers.txt not found. No browser mappings loaded.");
249+
return false;
250+
}
236251
using (StreamReader? sr = new("webbrowsers.txt"))
237252
{
238253
bool isDefault = true;
@@ -252,6 +267,11 @@ private bool PopulateCombos()
252267
private void PopulateWebSites()
253268
{
254269
webSiteList.Clear();
270+
if (!File.Exists("websites.txt"))
271+
{
272+
GlobalVar.Log("### websites.txt not found. No website mappings loaded.");
273+
return;
274+
}
255275
using var sr = new StreamReader("websites.txt");
256276
while (!sr.EndOfStream)
257277
{
@@ -311,6 +331,10 @@ public void ProcessCommand(string command)
311331
//Command Formatting
312332
string? originalCMD = command;
313333
lastCMD.Add(originalCMD);
334+
if (string.IsNullOrWhiteSpace(originalCMD))
335+
{
336+
return;
337+
}
314338
string[] splitWords = SplitWords(originalCMD);
315339
GlobalVar.Log($"!!! Processing Command: {originalCMD}");
316340

@@ -633,6 +657,7 @@ private static void MusicSearcher(string originalCMD)
633657

634658
private void MovieSearcher(string originalCMD)
635659
{
660+
// TODO: Rework movie search now that the server drive is no longer mapped.
636661
string? rawSearch = MovieSearch().Replace(originalCMD, "");
637662
GlobalVar.FileChoices.Clear();
638663
List<FileInfo> tempList2 = [];
@@ -1027,4 +1052,4 @@ public void ChangeBackgroundColor()
10271052
}
10281053

10291054
#endregion Change font/background Colors
1030-
}
1055+
}

DesktopShell/GlobalVar.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ public static partial class GlobalVar
3838

3939
// Security: PassPhrase is loaded from environment variable DESKTOPSHELL_PASSPHRASE
4040
// Fallback to "default" if not set (should be changed in production)
41-
public static readonly string PassPhrase = Environment.GetEnvironmentVariable("DESKTOPSHELL_PASSPHRASE") ?? "default";
41+
public static string PassPhrase => GetEnvValue("DESKTOPSHELL_PASSPHRASE") ?? "default";
42+
public static bool IsDefaultPassPhrase =>
43+
string.Equals(PassPhrase, "default", StringComparison.Ordinal);
4244

4345
// Optional TLS for TCP remote commands.
4446
// Enable with DESKTOPSHELL_TCP_TLS=1 and provide server cert via DESKTOPSHELL_TCP_TLS_PFX + DESKTOPSHELL_TCP_TLS_PFX_PASSWORD.
@@ -56,6 +58,7 @@ public static partial class GlobalVar
5658
public const string EnvQueueEnabled = "DESKTOPSHELL_QUEUE_ENABLED";
5759
public const string EnvQueueBaseUrl = "DESKTOPSHELL_QUEUE_BASEURL";
5860
public const string EnvQueueKeyBase64 = "DESKTOPSHELL_QUEUE_KEY_B64";
61+
public const string EnvQueueSharedSecret = "DESKTOPSHELL_QUEUE_SHARED_SECRET";
5962
public const string EnvCfAccessClientId = "DESKTOPSHELL_CF_ACCESS_CLIENT_ID";
6063
public const string EnvCfAccessClientSecret = "DESKTOPSHELL_CF_ACCESS_CLIENT_SECRET";
6164

@@ -127,10 +130,14 @@ public static void LogQueueEnvSummary()
127130
string enabledRaw = GetEnvValue(EnvQueueEnabled) ?? "";
128131
string? id = GetEnvValue(EnvCfAccessClientId);
129132
string? secret = GetEnvValue(EnvCfAccessClientSecret);
133+
string? sharedEnv = GetEnvValue(EnvQueueSharedSecret);
134+
string? shared = sharedEnv ?? "TUF@D^w3:xYsm,aLtY@ySCCo]%";
135+
string sharedSource = sharedEnv != null ? GetEnvSource(EnvQueueSharedSecret) : "code";
130136

131137
Log($"^^^ Queue env: {EnvQueueEnabled}='{enabledRaw}' (source={GetEnvSource(EnvQueueEnabled)}), " +
132138
$"{EnvCfAccessClientId}={(string.IsNullOrWhiteSpace(id) ? "missing" : "set")} (len={(id ?? "").Length}, source={GetEnvSource(EnvCfAccessClientId)}), " +
133-
$"{EnvCfAccessClientSecret}={(string.IsNullOrWhiteSpace(secret) ? "missing" : "set")} (len={(secret ?? "").Length}, source={GetEnvSource(EnvCfAccessClientSecret)})");
139+
$"{EnvCfAccessClientSecret}={(string.IsNullOrWhiteSpace(secret) ? "missing" : "set")} (len={(secret ?? "").Length}, source={GetEnvSource(EnvCfAccessClientSecret)}), " +
140+
$"{EnvQueueSharedSecret}={(string.IsNullOrWhiteSpace(shared) ? "missing" : "set")} (len={(shared ?? "").Length}, source={sharedSource})");
134141
}
135142

136143
public static void LogTcpEnvSummary()
@@ -149,6 +156,7 @@ public static void LogTcpEnvSummary()
149156
public static bool QueueEnabled => string.Equals(GetEnvValue(EnvQueueEnabled), "1", StringComparison.OrdinalIgnoreCase);
150157
public static string QueueBaseUrl => (GetEnvValue(EnvQueueBaseUrl) ?? "https://queue.dlamanna.com").TrimEnd('/');
151158
public static string? QueueKeyBase64 => GetEnvValue(EnvQueueKeyBase64);
159+
public static string? QueueSharedSecret => GetEnvValue(EnvQueueSharedSecret) ?? "TUF@D^w3:xYsm,aLtY@ySCCo]%";
152160
public static string? CfAccessClientId => GetEnvValue(EnvCfAccessClientId);
153161
public static string? CfAccessClientSecret => GetEnvValue(EnvCfAccessClientSecret);
154162

@@ -1153,4 +1161,4 @@ public static void ToolTip(string title, string body)
11531161
Run($@"{CurrentAssemblyDirectory}\Bin\ToolTipper.exe", $"{title} {body}");
11541162
}
11551163
#endregion
1156-
}
1164+
}

DesktopShell/MessageQueueClient.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,11 @@ private static void AddAuthHeaders(HttpRequestMessage request)
268268
{
269269
request.Headers.TryAddWithoutValidation(GlobalVar.HeaderCfAccessClientId, GlobalVar.CfAccessClientId);
270270
request.Headers.TryAddWithoutValidation(GlobalVar.HeaderCfAccessClientSecret, GlobalVar.CfAccessClientSecret);
271+
272+
if (!string.IsNullOrWhiteSpace(GlobalVar.QueueSharedSecret))
273+
{
274+
request.Headers.TryAddWithoutValidation("X-Queue-Token", GlobalVar.QueueSharedSecret);
275+
}
271276
}
272277

273278
private static string? DecodeCommand(PulledMessage msg)

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,24 @@ ____
2121
- `DESKTOPSHELL_QUEUE_KEY_B64` (optional): Base64-encoded AES key for queue message encryption.
2222
- `DESKTOPSHELL_CF_ACCESS_CLIENT_ID` / `DESKTOPSHELL_CF_ACCESS_CLIENT_SECRET` (required if queue enabled): Cloudflare Access service token credentials.
2323

24+
### Linux Harness Commands
25+
26+
When running in a sandboxed Linux harness (where the repo path is not writable), use these wrappers instead of calling `dotnet` directly:
27+
28+
```bash
29+
# Test wrapper (writes obj/bin/results under /tmp/desktopshell-harness)
30+
./scripts/test-harness-linux.sh
31+
32+
# Publish wrapper for win-x64 single-file
33+
./scripts/publish-win-x64-singlefile-harness-linux.sh
34+
```
35+
36+
Notes:
37+
- Wrappers force `BaseIntermediateOutputPath` and `BaseOutputPath` into `/tmp`.
38+
- Wrappers set `EnableWindowsTargeting=true` and clear/override fallback package behavior.
39+
- If package restore is blocked by network restrictions and required packages are missing from cache, restore/publish can still fail.
40+
- `DesktopShell.Tests` targets `net8.0-windows`; test execution itself may still require Windows behavior depending on test content.
41+
2442
This is mostly meant as a code example since many of the features of this program launch other programs I coded which are not bundled in this repository. If you want to try it anyways, add your [regular expression](https://regexr.com/), program executable path, and commandline arguments in separate lines in the shortcuts.txt file. Add one line spacing between statements, and if no commandline arguments are required, put a dash on the third line. To use your new regex either re-open the DesktopShell.exe program or type the command "rescan".
2543

2644
***
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
repo_root="$(cd "$script_dir/.." && pwd)"
6+
project_path="$repo_root/DesktopShell/DesktopShell.csproj"
7+
8+
configuration="${CONFIGURATION:-Release}"
9+
runtime="${RUNTIME:-win-x64}"
10+
self_contained="${SELF_CONTAINED:-true}"
11+
include_native="${INCLUDE_NATIVE_LIBRARIES_FOR_SELF_EXTRACT:-true}"
12+
13+
tmp_root="${DESKTOPSHELL_HARNESS_TMP:-/tmp/desktopshell-harness}"
14+
mkdir -p "$tmp_root" "$tmp_root/obj" "$tmp_root/bin" "$tmp_root/publish" "$tmp_root/nuget/packages" "$tmp_root/.dotnet"
15+
16+
export DOTNET_CLI_HOME="$tmp_root/.dotnet"
17+
export NUGET_PACKAGES="$tmp_root/nuget/packages"
18+
export NUGET_HTTP_CACHE_PATH="$tmp_root/nuget/http-cache"
19+
export NUGET_SCRATCH="$tmp_root/nuget/scratch"
20+
mkdir -p "$NUGET_HTTP_CACHE_PATH" "$NUGET_SCRATCH"
21+
22+
fallback_packages=""
23+
for d in /mnt/c/Users/*/.nuget/packages; do
24+
if [[ -d "$d" ]]; then
25+
fallback_packages="$d"
26+
break
27+
fi
28+
done
29+
30+
common_props=(
31+
"-p:EnableWindowsTargeting=true"
32+
"-p:BaseIntermediateOutputPath=$tmp_root/obj/"
33+
"-p:BaseOutputPath=$tmp_root/bin/"
34+
"-p:RestorePackagesPath=$NUGET_PACKAGES"
35+
)
36+
37+
if [[ -n "$fallback_packages" ]]; then
38+
common_props+=("-p:RestoreFallbackFolders=$fallback_packages")
39+
else
40+
common_props+=("-p:RestoreFallbackFolders=")
41+
fi
42+
43+
common_msbuild_flags=(
44+
"--disable-build-servers"
45+
"-m:1"
46+
"/nodeReuse:false"
47+
)
48+
49+
cd "$repo_root"
50+
51+
echo "[harness] restoring DesktopShell"
52+
dotnet restore "$project_path" \
53+
"${common_props[@]}" \
54+
"${common_msbuild_flags[@]}" \
55+
--ignore-failed-sources
56+
57+
echo "[harness] publishing single-file win-x64"
58+
dotnet publish "$project_path" \
59+
-c "$configuration" \
60+
-r "$runtime" \
61+
--self-contained "$self_contained" \
62+
-p:PublishSingleFile=true \
63+
"-p:IncludeNativeLibrariesForSelfExtract=$include_native" \
64+
"-p:PublishDir=$tmp_root/publish/" \
65+
--no-restore \
66+
"${common_props[@]}" \
67+
"${common_msbuild_flags[@]}" \
68+
"$@"
69+
70+
echo "[harness] publish output: $tmp_root/publish"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[CmdletBinding()]
2+
param(
3+
[string]$Configuration = 'Release',
4+
[string]$Runtime = 'win-x64',
5+
[switch]$SelfContained = $true,
6+
[switch]$IncludeNativeLibrariesForSelfExtract = $true
7+
)
8+
9+
$ErrorActionPreference = 'Stop'
10+
11+
$repoRoot = Split-Path -Parent $PSScriptRoot
12+
$projectPath = Join-Path $repoRoot 'DesktopShell\DesktopShell.csproj'
13+
14+
if (-not (Test-Path $projectPath)) {
15+
throw "Project not found: $projectPath"
16+
}
17+
18+
$sc = if ($SelfContained) { 'true' } else { 'false' }
19+
$includeNative = if ($IncludeNativeLibrariesForSelfExtract) { 'true' } else { 'false' }
20+
21+
$publishArgs = @(
22+
'publish',
23+
$projectPath,
24+
'-c', $Configuration,
25+
'-r', $Runtime,
26+
"--self-contained", $sc,
27+
"-p:PublishSingleFile=true",
28+
"-p:IncludeNativeLibrariesForSelfExtract=$includeNative"
29+
)
30+
31+
Write-Host "Running: dotnet $($publishArgs -join ' ')"
32+
& dotnet @publishArgs

scripts/test-harness-linux.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
repo_root="$(cd "$script_dir/.." && pwd)"
6+
7+
tmp_root="${DESKTOPSHELL_HARNESS_TMP:-/tmp/desktopshell-harness}"
8+
mkdir -p "$tmp_root" "$tmp_root/obj" "$tmp_root/bin" "$tmp_root/TestResults" "$tmp_root/nuget/packages" "$tmp_root/.dotnet"
9+
10+
export DOTNET_CLI_HOME="$tmp_root/.dotnet"
11+
export NUGET_PACKAGES="$tmp_root/nuget/packages"
12+
export NUGET_HTTP_CACHE_PATH="$tmp_root/nuget/http-cache"
13+
export NUGET_SCRATCH="$tmp_root/nuget/scratch"
14+
mkdir -p "$NUGET_HTTP_CACHE_PATH" "$NUGET_SCRATCH"
15+
16+
fallback_packages=""
17+
for d in /mnt/c/Users/*/.nuget/packages; do
18+
if [[ -d "$d" ]]; then
19+
fallback_packages="$d"
20+
break
21+
fi
22+
done
23+
24+
common_props=(
25+
"-p:EnableWindowsTargeting=true"
26+
"-p:BaseIntermediateOutputPath=$tmp_root/obj/"
27+
"-p:BaseOutputPath=$tmp_root/bin/"
28+
"-p:RestorePackagesPath=$NUGET_PACKAGES"
29+
)
30+
31+
if [[ -n "$fallback_packages" ]]; then
32+
common_props+=("-p:RestoreFallbackFolders=$fallback_packages")
33+
else
34+
common_props+=("-p:RestoreFallbackFolders=")
35+
fi
36+
37+
common_msbuild_flags=(
38+
"--disable-build-servers"
39+
"-m:1"
40+
"/nodeReuse:false"
41+
)
42+
43+
cd "$repo_root"
44+
45+
echo "[harness] restoring DesktopShell.sln"
46+
dotnet restore DesktopShell.sln \
47+
"${common_props[@]}" \
48+
"${common_msbuild_flags[@]}" \
49+
--ignore-failed-sources
50+
51+
echo "[harness] running tests"
52+
dotnet test DesktopShell.Tests/DesktopShell.Tests.csproj \
53+
-c Release \
54+
--no-restore \
55+
--results-directory "$tmp_root/TestResults" \
56+
"${common_props[@]}" \
57+
"${common_msbuild_flags[@]}" \
58+
"$@"

0 commit comments

Comments
 (0)