mirror of
https://github.com/ddeverill/SteamlessController.git
synced 2026-10-21 14:12:16 -05:00
People kept updating control mappings that did nothing, because Steamless mode was off and nothing said so until the in-window banner landed. The banner helps once you're looking at the window, but the fix people actually asked for is not needing to remember to flip the tray toggle every session. Manual mode now has its own "Enable on Launch" item, checked by default only for fresh installs — LoadSettings already returns before touching any member when the registry key doesn't exist at all, so that fork was free. An existing install keeps today's off-until-toggled behavior unless the user opts in, since flipping it under them wasn't part of the ask. Hidden outside Manual mode: the auto modes never make an "at launch" decision, they resolve control from Steam/game state continuously, so there is nothing for the item to mean there. Routes through EnableFromUser() at the end of Init(), after the profile is pushed — the same path the tray toggle and the remap window's banner button already share, so a fresh install's first acquire carries the right bindings and goes through the same elevated-helper registration as a manual click. Bumped to 1.23; this is the last change queued before packaging. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
171 lines
8.2 KiB
Plaintext
171 lines
8.2 KiB
Plaintext
; Script generated by the Inno Setup Script Wizard.
|
|
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
|
; Non-commercial use only
|
|
|
|
#define MyAppName "SteamlessController"
|
|
#define MyAppVersion "1.23"
|
|
#define ViGEmSetup "ViGEmBus_1.22.0_x64_x86_arm64.exe"
|
|
#define MyAppPublisher "Dylan Deverill"
|
|
#define MyAppURL "https://github.com/ddeverill/SteamlessController"
|
|
#define MyAppExeName "SteamlessController.exe"
|
|
|
|
; Where the packaged binaries come from, spelled once so the version check
|
|
; below and the [Files] entries cannot drift apart.
|
|
#define BuildDir "build\release\Release\"
|
|
|
|
; Refuse to build an installer around a stale executable.
|
|
;
|
|
; The trap this exists for: the Visual Studio generator is multi-config, so
|
|
; CMAKE_BUILD_TYPE does nothing and "cmake --build build/release" quietly
|
|
; produces DEBUG. The Release directory packaged here keeps whatever was in it
|
|
; from the last correct build, which can be weeks old. Setup then stamps
|
|
; MyAppVersion on the metadata and installs an executable that reports its own
|
|
; older version — an installer that says one thing while Add/Remove Programs,
|
|
; the log banner and the features present all say another.
|
|
;
|
|
; That shipped once, to the #95 reporter, and cost a round trip to work out.
|
|
; Nothing about it was visible: setup succeeded, the version in Add/Remove
|
|
; Programs was right, and only the app's own log gave it away.
|
|
;
|
|
; Build it properly with: cmake --build --preset release
|
|
; (the preset carries "configuration": "Release"; the bare path form does not)
|
|
; Note the "../": [Files] resolves against SourceDir, but the preprocessor
|
|
; resolves against this script's own directory.
|
|
#define ExeVersion GetStringFileInfo("../" + BuildDir + MyAppExeName, "FileVersion")
|
|
#if ExeVersion != MyAppVersion
|
|
; #error takes its line literally and evaluates nothing, so the versions
|
|
; are printed by #pragma message, which does.
|
|
#pragma message "Packaged " + MyAppExeName + " is version " + ExeVersion + " but this script builds " + MyAppVersion
|
|
#error The packaged executable is stale - see the message above. Run: cmake --build --preset release
|
|
#endif
|
|
|
|
[Setup]
|
|
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
|
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
|
AppId={{4E6FF864-969A-44C6-B4AC-848F22D5EF57}
|
|
AppName={#MyAppName}
|
|
AppVersion={#MyAppVersion}
|
|
;AppVerName={#MyAppName} {#MyAppVersion}
|
|
AppPublisher={#MyAppPublisher}
|
|
AppPublisherURL={#MyAppURL}
|
|
AppSupportURL={#MyAppURL}
|
|
AppUpdatesURL={#MyAppURL}
|
|
DefaultDirName={autopf}\{#MyAppName}
|
|
UninstallDisplayIcon={app}\{#MyAppExeName}
|
|
SourceDir=..
|
|
; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run
|
|
; on anything but x64 and Windows 11 on Arm.
|
|
ArchitecturesAllowed=x64compatible
|
|
; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the
|
|
; install be done in "64-bit mode" on x64 or Windows 11 on Arm,
|
|
; meaning it should use the native 64-bit Program Files directory and
|
|
; the 64-bit view of the registry.
|
|
ArchitecturesInstallIn64BitMode=x64compatible
|
|
DisableProgramGroupPage=yes
|
|
; Uncomment the following line to run in non administrative install mode (install for current user only).
|
|
;PrivilegesRequired=lowest
|
|
OutputBaseFilename=SteamlessController-Setup
|
|
SetupIconFile=resources\SteamControllerON.ico
|
|
SolidCompression=yes
|
|
WizardStyle=modern
|
|
|
|
[Languages]
|
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
|
|
|
[Tasks]
|
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
|
|
|
[Files]
|
|
Source: "{#BuildDir}{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
|
Source: "{#BuildDir}SteamlessDeviceCycle.exe"; DestDir: "{app}"; Flags: ignoreversion
|
|
; Setup's driver check, and the thing to ask a user to run when a controller
|
|
; never reaches a game. Installed rather than temporary for the second reason.
|
|
Source: "{#BuildDir}ViGEmBusProbe.exe"; DestDir: "{app}"; Flags: ignoreversion
|
|
Source: "resources\{#ViGEmSetup}"; DestDir: "{tmp}"; Flags: deleteafterinstall
|
|
|
|
[Icons]
|
|
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
|
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
|
|
|
[Run]
|
|
; ViGEmBus uses MSI-style silent switches; /install is rejected by the 1.22.0 bootstrapper.
|
|
Filename: "{tmp}\{#ViGEmSetup}"; Parameters: "/qn /norestart"; StatusMsg: "Installing ViGEmBus driver..."; Flags: waituntilterminated
|
|
; Register the elevated on-demand device-cycle task while the installer is
|
|
; already elevated, so users never see a UAC prompt from the app itself.
|
|
Filename: "{app}\SteamlessDeviceCycle.exe"; Parameters: "--register"; StatusMsg: "Registering controller helper task..."; Flags: waituntilterminated runhidden
|
|
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
|
|
|
[UninstallRun]
|
|
Filename: "{app}\SteamlessDeviceCycle.exe"; Parameters: "--unregister"; RunOnceId: "RemoveCycleTask"; Flags: waituntilterminated runhidden
|
|
|
|
[Code]
|
|
// Did ViGEmBus actually install? Established the way the app establishes it at
|
|
// runtime — by enumerating the ViGEm bus interface — because every cheaper
|
|
// answer has been measured and found to lie:
|
|
//
|
|
// * the bundle exits 0 when it finds a related product already registered
|
|
// and decides there is nothing for it to do
|
|
// * the registry records the product whether or not a driver ever landed
|
|
// * the driver's own version is no guide either: 1.22.0 ships a binary still
|
|
// stamped 1.21.442.0
|
|
//
|
|
// Reported in #68: with another program's rebranded ViGEm already present,
|
|
// setup looked entirely successful and left the machine with no working bus.
|
|
// The user found out when they clicked Enable Steamless Mode.
|
|
function ViGEmBusPresent(): Boolean;
|
|
var
|
|
ResultCode: Integer;
|
|
begin
|
|
// Assume the best when the check itself cannot run. A missing or broken
|
|
// probe is our bug, and telling every user their driver failed on account of
|
|
// it would be worse than saying nothing at all.
|
|
Result := True;
|
|
if not Exec(ExpandConstant('{app}\ViGEmBusProbe.exe'), '', '',
|
|
SW_HIDE, ewWaitUntilTerminated, ResultCode) then
|
|
begin
|
|
Log('ViGEmBus verification: probe could not be run');
|
|
Exit;
|
|
end;
|
|
Log('ViGEmBus verification: probe exit code ' + IntToStr(ResultCode));
|
|
Result := ResultCode = 0;
|
|
end;
|
|
|
|
procedure CurStepChanged(CurStep: TSetupStep);
|
|
var
|
|
WarningText: String;
|
|
begin
|
|
// ssPostInstall runs after the [Run] entries above, so the driver installer
|
|
// has finished by the time this fires. Worth stating because it is
|
|
// load-bearing: were that ordering ever wrong, every healthy install would
|
|
// warn. That is a loud failure rather than a quiet one, which is why the
|
|
// check sits here rather than behind a wrapper built to guarantee ordering.
|
|
if CurStep <> ssPostInstall then
|
|
Exit;
|
|
if ViGEmBusPresent() then
|
|
Exit;
|
|
|
|
WarningText :=
|
|
'SteamlessController is installed, but the ViGEmBus driver is not.' + #13#10 + #13#10 +
|
|
'That driver is what presents your controller to games. Setup ran its ' +
|
|
'installer, but no virtual gamepad bus is present afterwards. Usually this ' +
|
|
'means another program has already registered a version of it — Oculus and ' +
|
|
'Virtual Desktop both ship their own copy — which stops the bundled ' +
|
|
'installer from doing anything.' + #13#10 + #13#10 +
|
|
'To finish:' + #13#10 + #13#10 +
|
|
' 1. Download ViGEmBus from' + #13#10 +
|
|
' https://github.com/nefarius/ViGEmBus/releases/latest' + #13#10 +
|
|
' 2. Run it, choosing Repair if it offers that rather than a fresh install' + #13#10 +
|
|
' 3. Start SteamlessController — it picks the driver up on its own,' + #13#10 +
|
|
' with no reinstall and no restart needed' + #13#10 + #13#10 +
|
|
'To check again later, run ViGEmBusProbe.exe from the installation folder.';
|
|
|
|
// An unattended install must not stop on a dialog nobody is there to close.
|
|
// The Inno log carries the same finding either way, and so will the app's
|
|
// event log the first time somebody enables Steamless Mode.
|
|
if WizardSilent() then
|
|
Log('ViGEmBus verification: no bus present after install (silent, not shown)')
|
|
else
|
|
MsgBox(WarningText, mbInformation, MB_OK);
|
|
end;
|
|
|