-
Notifications
You must be signed in to change notification settings - Fork 6
Build and Publish
Technical reference for building, publishing, and releasing PadForge.
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
| 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.
dotnet publish -c ReleaseOutput path:
PadForge.App/bin/Release/net8.0-windows/win-x64/publish/PadForge.exe
Critical: Always use
dotnet publish, neverdotnet build. The project is configured for single-file self-contained publish.dotnet buildproduces a non-functional multi-file output that won't run correctly as a portable deployment.
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)
<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" /><TargetFramework>net8.0-windows</TargetFramework>
<!-- No NuGet dependencies -- pure P/Invoke and data types -->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.
| 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.
<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.
<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.
<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.
<Resource Include="2DModels\**\*.png" />PNG overlay images for 2D controller schematic view. Loaded as WPF pack URIs.
<Resource Include="Resources\Xbox Series Controller - Front.png" />
<Resource Include="Resources\Xbox Series Controller - Top.png" />
<Content Include="Resources\PadForge.ico" />PadForge is a portable application — no installer required.
Copy the publish output to any folder:
cp PadForge.App/bin/Release/net8.0-windows/win-x64/publish/PadForge.exe C:\PadForge\PadForge.exeThe 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.
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).
Edit both AssemblyInfo files:
PadForge.App/Properties/AssemblyInfo.csPadForge.Engine/Properties/AssemblyInfo.cs
dotnet publish -c Releasecp PadForge.App/bin/Release/net8.0-windows/win-x64/publish/PadForge.exe C:\PadForge\PadForge.exeRun C:\PadForge\PadForge.exe and verify functionality.
git add -A
git commit -m "Release vX.Y.Z"
git pushcd PadForge.App/bin/Release/net8.0-windows/win-x64/publish
zip -r PadForge-vX.Y.Z-win-x64.zip .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.zipUse --prerelease for beta/RC releases. Use --latest to make it the default download.
The tools/ directory contains standalone diagnostic utilities:
cd tools/DsuDiag
dotnet runReal-time DSU/Cemuhook client that displays received motion data per slot. Useful for verifying gyro/accelerometer axis mapping.
cd tools/vJoy/Test
dotnet run -- axes=6 buttons=11 povs=1Creates a vJoy device with the specified configuration and runs an input test with WinMM readback verification.
cd tools/vJoy/FfbTest
dotnet runDirectInput force feedback test tool with interactive menu for ConstantForce and Sine effects.
| 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