Files
TeslaSuite/Contract/Tesla.Contract.csproj
T
CydandClaude Fable 5 8730b9b966 XP11: single net40 binary runs on XP SP3 through Windows 11
Merge TeslaLauncherService (Session 0) + TeslaLauncherAgent (tray) into one
userland TeslaLauncher.exe. The split existed only to work around Vista+
Session 0 isolation; running everything in the auto-logged-in admin session
needs no service, no named pipe, and no flat<->wire conversion layer. The
original Elsewhen software was likewise a single binary.

net40 is the newest framework XP SP3 can install, and net40 assemblies load
in-place on the 4.8 runtime in Win10/11 -- one exe covers both.

- Contract: multi-target net48;net40. The net40 leg of PodRpcProtocol uses
  Newtonsoft.Json (STJ has no net40 target); JSON is shape-identical on the
  wire, and the request reader keeps date strings raw so Ping echoes
  byte-identically. Console keeps the untouched net48/STJ leg.
- MiniZip.cs: central-directory ZIP extractor (stored/deflate/ZIP64) since
  net40 has no ZipFile; zip-slip guarded.
- SecureConfig: RSACryptoServiceProvider instead of RSA.Create (net46+),
  no leaveOpen BinaryWriter/Reader, struct instead of ValueTuple, and no
  SetCompatibleTextRenderingDefault on the passcode thread (the merged app
  already has a form). netsh "interface ip" syntax was already XP-correct.
- Volume: nircmd -> CoreAudio (Vista+) -> winmm waveOutSetVolume (XP).
- Paths: CommonApplicationData resolved per-OS (XP has no C:\ProgramData);
  launcher log moved next to the key/config in the data dir.
- install.bat: dual-OS (cacls/icacls, netsh firewall/advfirewall, dism and
  UAC/notification steps skipped on XP, .NET 4.0 redist check, XP DHCP reset
  via netsh); no service registration -- HKLM Run key + auto-login on both;
  RegisterApplicationRestart supplies crash-restart on Vista+.
- Bench switches: /skipconfig, /port:NNNN.

Verified: Console + diff suite (103 tests) still green on the net48 leg;
E2E smoke test drove the net40 launcher over real TCP with the Console's own
PodManagerConnection (STJ client vs Newtonsoft server) -- Ping echo, volume,
app registry, launch/kill/watch, InstallProduct zip transfer + extract, and
uninstall orphan cleanup: 17/17 pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 18:59:06 -05:00

61 lines
2.9 KiB
XML

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- net48: the Console (and the client/crypto stack under Client/**).
net40: the XP11 single-binary Launcher — the oldest framework installable
on Windows XP SP3, and net40 assemblies run in-place on the 4.8 runtime,
so ONE launcher binary covers XP SP3 through Windows 11. -->
<TargetFrameworks>net48;net40</TargetFrameworks>
<!-- CRITICAL: the output assembly MUST be named TeslaConsoleLaunchLib at
version 1.0.0.0. BinaryFormatter embeds the assembly name in the wire
stream and the Console resolves the wire types by that simple name, so
renaming the assembly would change the protocol. This is a pure
refactor that keeps the bytes identical. -->
<AssemblyName>TeslaConsoleLaunchLib</AssemblyName>
<RootNamespace>Tesla.Net</RootNamespace>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<Version>1.0.0.0</Version>
<Nullable>disable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<!-- Decompiled-style source: designer-ish fields, BinaryFormatter on net6. -->
<NoWarn>$(NoWarn);SYSLIB0011</NoWarn>
</PropertyGroup>
<!-- .NET Framework reference assemblies so the project builds without a full
targeting pack (resolves per-TFM, covers net40 and net48). -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
</ItemGroup>
<!-- JSON serializer per leg. System.Text.Json has no net40 target, so the
net40 leg of PodRpcProtocol.cs uses Newtonsoft.Json (which still ships
lib/net40). The JSON bytes on the wire are shape-identical; the
XpWireCompatTests exercise STJ-client <-> Newtonsoft-server for real. -->
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net40'">
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<!-- The TCP/OFB client (Client/**) is net48-only: it depends on the crypto-stream
handshake in TeslaSecureConfiguration.dll. The Launcher is the SERVER end of
this protocol and never references these classes, so the net40 leg carries
only the wire data types + PodRpc framing. -->
<ItemGroup Condition="'$(TargetFramework)' != 'net48'">
<Compile Remove="Client\**\*.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<!-- Source-built secure-config (PodConfigurationServer.NegotiateCryptoStreams),
emitting assembly TeslaSecureConfiguration. net48-only, same as Client/**. -->
<ProjectReference Include="..\SecureConfig\Tesla.SecureConfig.csproj" />
</ItemGroup>
</Project>