Skip to content

Build and Publish

hifihedgehog edited this page Mar 6, 2026 · 32 revisions

Build and Publish

Technical reference for building, publishing, and releasing PadForge.


Solution Structure

PadForge.sln
├── PadForge.Engine/          Class library (net8.0-windows)
│   ├── Common/               SDL3 P/Invoke, input types, device wrappers
│   ├── Data/                 PadSetting, UserDevice, UserSetting
│   └── Properties/           AssemblyInfo.cs
│
├── PadForge.App/             WPF Application (net8.0-windows)
│   ├── Common/               SettingsManager, DriverInstaller, InputManager pipeline
│   ├── Views/                XAML pages and code-behind
│   ├── ViewModels/           MVVM ViewModels
│   ├── Services/             InputService, SettingsService, DeviceService, etc.
│   ├── WebAssets/             HTML/CSS/JS for browser virtual controller
│   ├── Models3D/             3D model classes + OBJ meshes (3DModels/)
│   ├── Models2D/             2D overlay layout classes
│   ├── 2DModels/             PNG overlay images (DS4/, XBOX360/)
│   ├── Converter/            WPF value converters
│   ├── Controls/             Custom controls (RangeSlider)
│   ├── Resources/            Icons, SDL3 DLL, embedded driver installers
│   └── Properties/           AssemblyInfo.cs
│
└── tools/
    ├── DsuDiag/              DSU/Cemuhook diagnostic client
    ├── vJoy/Test/            vJoy device creation + input test
    └── vJoy/FfbTest/         DirectInput FFB test tool

Prerequisites

Requirement Version Notes
.NET SDK 8.0+ net8.0-windows target framework
Windows 10/11 x64 WPF + Windows-specific P/Invoke
Visual Studio (optional) 2022+ Not required; dotnet CLI suffices

All native DLLs, driver installers, and model assets are included in the repository. No external downloads needed to build.

Build Command

dotnet publish -c Release

Output path:

PadForge.App/bin/Release/net8.0-windows/win-x64/publish/PadForge.exe

Critical: Always use dotnet publish, never dotnet build. The project is configured for single-file self-contained publish. dotnet build produces a non-functional multi-file output that won't run correctly as a portable deployment.

What dotnet publish Does

The csproj sets these publish properties:

<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>

This produces a single PadForge.exe (~85 MB) that:

  • Bundles the .NET 8 runtime (no install required on target)
  • Compresses all managed assemblies into the single file
  • Extracts native libraries to a temp directory at runtime
  • Includes all embedded resources (driver installers, 3D models)

Project Configuration Details

PadForge.App.csproj

<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>  <!-- For NotifyIcon system tray -->
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>  <!-- Manual AssemblyInfo.cs -->

WinForms implicit using removal — prevents System.Drawing / System.Windows.Forms ambiguity with WPF types:

<Using Remove="System.Drawing" />
<Using Remove="System.Windows.Forms" />

PadForge.Engine.csproj

<TargetFramework>net8.0-windows</TargetFramework>
<!-- No NuGet dependencies -- pure P/Invoke and data types -->

Version Management

Version is set manually in Properties/AssemblyInfo.cs (both projects):

[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]

GenerateAssemblyInfo is false in both projects to use these manual files instead of auto-generated attributes.

NuGet Dependencies

Package Version Purpose
ModernWpfUI 0.9.6 Fluent Design theme for WPF
HelixToolkit.Core.Wpf 2.27.3 3D viewport rendering (OBJ models)
CommunityToolkit.Mvvm 8.2.2 MVVM: ObservableObject, RelayCommand
Nefarius.ViGEm.Client 1.21.256 ViGEm virtual controller client API

PadForge.Engine has zero NuGet dependencies — all SDL3 and system interop is via raw P/Invoke.

Native DLLs and Embedded Resources

SDL3 DLL (Content — copied to output)

<Content Include="Resources\SDL3\x64\SDL3.dll" Link="SDL3.dll">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\SDL3\x64\libusb-1.0.dll" Link="libusb-1.0.dll">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

Link="SDL3.dll" flattens the file to the output root (next to PadForge.exe) instead of preserving the Resources\SDL3\x64\ subdirectory.

The SDL3.dll is a custom fork with WinUSB support for Switch 2 Pro Controller. See SDL3 Integration for details.

Both have Condition="Exists(...)" so builds succeed before the DLL is placed.

Embedded Driver Installers (EmbeddedResource)

<EmbeddedResource Include="Resources\ViGEmBus_1.22.0_x64_x86_arm64.exe" />
<EmbeddedResource Include="Resources\HidHide_1.5.230_x64.exe" />
<EmbeddedResource Include="Resources\vJoyDriver.zip" />

These are extracted at runtime by DriverInstaller.cs when the user clicks Install in Settings. They are not needed to run PadForge — only for optional driver installation.

3D Model Assets (EmbeddedResource)

<EmbeddedResource Include="3DModels\**\*.obj" />

OBJ mesh files for Xbox 360 (31 files) and DualShock 4 (36 files) controller visualization. Loaded by ControllerModelBase.LoadModel() at runtime.

2D Model Assets (Resource)

<Resource Include="2DModels\**\*.png" />

PNG overlay images for 2D controller schematic view. Loaded as WPF pack URIs.

Other Resources

<Resource Include="Resources\Xbox Series Controller - Front.png" />
<Resource Include="Resources\Xbox Series Controller - Top.png" />
<Content Include="Resources\PadForge.ico" />

Deployment

PadForge is a portable application — no installer required.

Local Deployment

Copy the publish output to any folder:

cp PadForge.App/bin/Release/net8.0-windows/win-x64/publish/PadForge.exe C:\PadForge\PadForge.exe

The following files must be alongside PadForge.exe:

  • SDL3.dll — SDL3 native library
  • libusb-1.0.dll — WinUSB access for Switch 2 Pro Controller

These are automatically placed by dotnet publish.

First Run

On first run, PadForge creates PadForge.xml in the same directory as the executable to store all settings, mappings, and profiles.

If the vJoy driver is installed, PadForge requests administrator privileges on startup (auto-elevation in App.xaml.cs).

Release Workflow

1. Update Version (if needed)

Edit both AssemblyInfo files:

  • PadForge.App/Properties/AssemblyInfo.cs
  • PadForge.Engine/Properties/AssemblyInfo.cs

2. Build

dotnet publish -c Release

3. Deploy and Test

cp PadForge.App/bin/Release/net8.0-windows/win-x64/publish/PadForge.exe C:\PadForge\PadForge.exe

Run C:\PadForge\PadForge.exe and verify functionality.

4. Commit and Push

git add -A
git commit -m "Release vX.Y.Z"
git push

5. Create Binary Zip

cd PadForge.App/bin/Release/net8.0-windows/win-x64/publish
zip -r PadForge-vX.Y.Z-win-x64.zip .

6. Create GitHub Release

gh release create vX.Y.Z --title "PadForge vX.Y.Z" --notes "Release notes here"
gh release upload vX.Y.Z PadForge-vX.Y.Z-win-x64.zip

Use --prerelease for beta/RC releases. Use --latest to make it the default download.

Diagnostic Tools

The tools/ directory contains standalone diagnostic utilities:

DsuDiag

cd tools/DsuDiag
dotnet run

Real-time DSU/Cemuhook client that displays received motion data per slot. Useful for verifying gyro/accelerometer axis mapping.

VJoyTest

cd tools/vJoy/Test
dotnet run -- axes=6 buttons=11 povs=1

Creates a vJoy device with the specified configuration and runs an input test with WinMM readback verification.

FfbTest

cd tools/vJoy/FfbTest
dotnet run

DirectInput force feedback test tool with interactive menu for ConstantForce and Sine effects.

Troubleshooting Build Issues

Issue Cause Fix
SDL3.dll not found at runtime DLL not in Resources\SDL3\x64\ Download from SDL3 releases or build from fork
Missing WPF types Using dotnet build instead of dotnet publish Always use dotnet publish -c Release
System.Drawing ambiguity WinForms implicit usings conflict Ensure <Using Remove="System.Drawing" /> is in csproj
HelixToolkit errors Package restore failed Run dotnet restore first
Large exe size (~85MB) Expected — self-contained with runtime Use EnableCompressionInSingleFile (already enabled)

See also: Architecture Overview | Engine Library | Settings and Serialization

Clone this wiki locally