templates: Add option to extract to Windows installer

Adds back the removed portable installation method, but in a different way that shouldn't be possible to mess up. The original method had to be removed due to an excessive amount of poor video guides on how to install StreamFX, many of which went out of their way to ignore the Installation Guide.

Fixes #542
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2021-10-17 13:44:54 +02:00
parent 4fea923371
commit 2f79f30e5b

View file

@ -37,13 +37,18 @@ VersionInfoDescription={#MyAppName} Setup
ArchitecturesInstallIn64BitMode=x64 arm64 ia64 ArchitecturesInstallIn64BitMode=x64 arm64 ia64
ArchitecturesAllowed=@ARCH@ ArchitecturesAllowed=@ARCH@
; Installation Modes
PrivilegesRequired=lowest
PrivilegesRequiredOverridesAllowed=dialog commandline
; Wizard Information ; Wizard Information
WizardStyle=modern WizardStyle=modern
WizardResizable=yes WizardResizable=yes
SetupIconFile="@PROJECT_SOURCE_DIR@/media/icon.ico" SetupIconFile="@PROJECT_SOURCE_DIR@/media/icon.ico"
; Other Information ; Other Information
UsePreviousAppDir=yes UsePreviousAppDir=no
Uninstallable=not IsPortablePagePortableChoiceChecked()
DefaultDirName={code:GetDefaultDirectory} DefaultDirName={code:GetDefaultDirectory}
DefaultGroupName={#MyAppName} DefaultGroupName={#MyAppName}
AllowNoIcons=yes AllowNoIcons=yes
@ -67,10 +72,28 @@ Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
[Code] [Code]
// ------------------------------------------------------------------------------------------------------------------ //
var
oPortablePageStaticChoice: TNewRadioButton;
oPortablePagePortableChoice: TNewRadioButton;
function FindRegistryKey(): String; forward;
function GetDefaultDirectory(Value: String): String; forward;
function GetUninstallerPath(): String; forward;
function IsUpgrade(): Boolean; forward;
function IsPortablePagePortableChoiceChecked(): Boolean; forward;
function UninstallOldVersion(): Integer; forward;
procedure OnPortablePagePortableChoiceClick(Sender: TObject); forward;
procedure OnPortablePageStaticChoiceClick(Sender: TObject); forward;
function CreatePortablePage: TWizardPage; forward;
procedure InitializeWizard; forward;
function ShouldSkipPage(PageID: Integer): Boolean; forward;
function PrepareToInstall(var NeedsRestart: Boolean): String; forward;
// ------------------------------------------------------------------------------------------------------------------ // // ------------------------------------------------------------------------------------------------------------------ //
function FindRegistryKey(): String; function FindRegistryKey(): String;
begin begin
Result := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting('AppId')}_is1'); Result := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting('AppId')}_is1');
end; end;
// ------------------------------------------------------------------------------------------------------------------ // // ------------------------------------------------------------------------------------------------------------------ //
@ -86,25 +109,25 @@ begin
RegQueryStringValue(HKA64, FindRegistryKey(), 'InstallLocation', sInstallPath); RegQueryStringValue(HKA64, FindRegistryKey(), 'InstallLocation', sInstallPath);
// 2. If empty, try and find the "Local Machine" installation of OBS Studio. // 2. If empty, try and find the "Local Machine" installation of OBS Studio.
if (sInstallPath = '') then if (sInstallPath = '') then
RegQueryStringValue(HKLM64, 'SOFTWARE\OBS Studio', '', sInstallPath); RegQueryStringValue(HKLM64, 'SOFTWARE\OBS Studio', '', sInstallPath);
// 3. If empty, try and find the "Current User" installation of OBS Studio. // 3. If empty, try and find the "Current User" installation of OBS Studio.
if (sInstallPath = '') then if (sInstallPath = '') then
RegQueryStringValue(HKCU64, 'SOFTWARE\OBS Studio', '', sInstallPath); RegQueryStringValue(HKCU64, 'SOFTWARE\OBS Studio', '', sInstallPath);
// 4. If empty, try and find the 32-bit "Local Machine" installation of OBS Studio. // 4. If empty, try and find the 32-bit "Local Machine" installation of OBS Studio.
if (sInstallPath = '') then if (sInstallPath = '') then
RegQueryStringValue(HKLM32, 'SOFTWARE\OBS Studio', '', sInstallPath); RegQueryStringValue(HKLM32, 'SOFTWARE\OBS Studio', '', sInstallPath);
// 5. If empty, try and find the 32-bit "Current User" installation of OBS Studio. // 5. If empty, try and find the 32-bit "Current User" installation of OBS Studio.
if (sInstallPath = '') then if (sInstallPath = '') then
RegQueryStringValue(HKCU32, 'SOFTWARE\OBS Studio', '', sInstallPath); RegQueryStringValue(HKCU32, 'SOFTWARE\OBS Studio', '', sInstallPath);
// 6. If empty, just use the default path. // 6. If empty, just use the default path.
if (sInstallPath = '') then if (sInstallPath = '') then
sInstallPath := ExpandConstant('{commonpf}\obs-studio'); sInstallPath := ExpandConstant('{commonpf}\obs-studio');
Result := sInstallPath Result := sInstallPath
end; end;
@ -133,7 +156,7 @@ end;
// ------------------------------------------------------------------------------------------------------------------ // // ------------------------------------------------------------------------------------------------------------------ //
function IsUpgrade(): Boolean; function IsUpgrade(): Boolean;
begin begin
Result := (GetUninstallerPath() <> ''); Result := (not IsPortablePagePortableChoiceChecked()) and (GetUninstallerPath() <> '');
end; end;
// ------------------------------------------------------------------------------------------------------------------ // // ------------------------------------------------------------------------------------------------------------------ //
@ -154,6 +177,168 @@ begin
end; end;
end; end;
// ------------------------------------------------------------------------------------------------------------------ //
procedure OnPortablePagePortableChoiceClick(Sender: TObject);
begin
oPortablePageStaticChoice.Checked := False;
oPortablePagePortableChoice.Checked := True;
end;
procedure OnPortablePageStaticChoiceClick(Sender: TObject);
begin
if (not oPortablePageStaticChoice.Enabled) then begin
OnPortablePagePortableChoiceClick(Sender);
end else begin
oPortablePageStaticChoice.Checked := True;
oPortablePagePortableChoice.Checked := False;
end;
end;
function IsPortablePagePortableChoiceChecked(): Boolean;
begin
Result := oPortablePagePortableChoice.Checked;
end;
function CreatePortablePage: TWizardPage;
var
oPage: TWizardPage;
oStaticPanel: TPanel;
oStaticChoice: TNewRadioButton;
oStaticText: TLabel;
oStaticWarningText: TLabel;
oPortablePanel: TPanel;
oPortableChoice: TNewRadioButton;
oPortableText: TLabel;
begin
// Build a page that asks a user if they want to use Movable or Static installation.
oPage := CreateCustomPage(wpLicense,
'Installation Type',
'Select how to install StreamFX on your System');
oStaticPanel := TPanel.Create(oPage);
oStaticPanel.Parent := oPage.Surface;
oStaticPanel.ParentBackground := False;
oStaticPanel.Left := ScaleX(5);
oStaticPanel.Top := ScaleY(5);
oStaticPanel.Width := oPage.SurfaceWidth - ScaleX(10);
oStaticPanel.Height := ScaleY(100);
oStaticPanel.Anchors := [akLeft, akTop, akRight];
oStaticPanel.Color := clWindow;
oStaticPanel.BevelKind := bkTile;
oStaticPanel.BevelInner := bvNone;
oStaticPanel.BevelOuter := bvRaised;
oStaticPanel.BevelWidth := 1;
oStaticPanel.OnClick := @OnPortablePageStaticChoiceClick;
oStaticChoice := TNewRadioButton.Create(oStaticPanel);
oPortablePageStaticChoice := oStaticChoice;
oStaticChoice.Parent := oStaticPanel;
oStaticChoice.ParentBackground := False;
oStaticChoice.Left := ScaleX(5);
oStaticChoice.Top := ScaleY(5);
oStaticChoice.Width := oStaticPanel.Width - ScaleX(10);
oStaticChoice.Height := ScaleY(20);
oStaticChoice.Anchors := [akLeft, akTop, akRight];
oStaticChoice.Caption := 'Static';
oStaticChoice.Font.Style := [fsBold];
oStaticChoice.OnClick := @OnPortablePageStaticChoiceClick;
oStaticText := TLabel.Create(oStaticPanel);
oStaticText.Parent := oStaticPanel;
oStaticText.AutoSize := False;
oStaticText.Left := ScaleX(5);
oStaticText.Top := ScaleY(5) + oStaticChoice.Top + oStaticChoice.Height;
oStaticText.Width := oStaticPanel.Width - ScaleX(10);
oStaticText.Height := oStaticPanel.Height - ScaleX(5) - oStaticText.Top;
oStaticText.Anchors := [akLeft, akTop, akRight];
oStaticText.WordWrap := True
oStaticText.Caption := 'Install for use in a static version of OBS Studio, with all necessary features to support it.';
oStaticText.OnClick := @OnPortablePageStaticChoiceClick;
oPortablePanel := TPanel.Create(oPage);
oPortablePanel.Parent := oPage.Surface;
oPortablePanel.ParentBackground := False;
oPortablePanel.Left := ScaleX(5);
oPortablePanel.Top := ScaleY(5) + oStaticPanel.Top + oStaticPanel.Height;
oPortablePanel.Width := oPage.SurfaceWidth - ScaleX(10);
oPortablePanel.Height := ScaleY(100);
oPortablePanel.Anchors := [akLeft, akTop, akRight];
oPortablePanel.Color := clWindow;
oPortablePanel.BevelKind := bkTile;
oPortablePanel.BevelInner := bvNone;
oPortablePanel.BevelOuter := bvRaised;
oPortablePanel.BevelWidth := 1;
oPortablePanel.OnClick := @OnPortablePagePortableChoiceClick;
oPortableChoice := TNewRadioButton.Create(oPortablePanel);
oPortablePagePortableChoice := oPortableChoice;
oPortableChoice.Parent := oPortablePanel;
oPortableChoice.ParentBackground := False;
oPortableChoice.Left := ScaleX(5);
oPortableChoice.Top := ScaleY(5);
oPortableChoice.Width := oPortablePanel.Width - ScaleX(10);
oPortableChoice.Height := ScaleY(20);
oPortableChoice.Anchors := [akLeft, akTop, akRight];
oPortableChoice.Caption := 'Portable';
oPortableChoice.Font.Style := [fsBold];
oPortableChoice.OnClick := @OnPortablePagePortableChoiceClick;
oPortableText := TLabel.Create(oPortablePanel);
oPortableText.Parent := oPortablePanel;
oPortableText.AutoSize := False;
oPortableText.Left := ScaleX(5);
oPortableText.Top := ScaleY(5) + oPortableChoice.Top + oPortableChoice.Height;
oPortableText.Width := oPortablePanel.Width - ScaleX(10);
oPortableText.Height := oPortablePanel.Height - ScaleX(5) - oPortableText.Top;
oPortableText.Anchors := [akLeft, akTop, akRight];
oPortableText.WordWrap := True
oPortableText.Caption := 'Install for use in portable or multi-environment scenarios, which require StreamFX to not be tied to the System itself. The uninstaller, automatic updates and other system-dependent features will be unavailable.';
oPortableText.OnClick := @OnPortablePagePortableChoiceClick;
if (not IsAdmin()) then begin
oStaticWarningText := TLabel.Create(oStaticPanel);
oStaticWarningText.Parent := oStaticPanel;
oStaticWarningText.AutoSize := False;
oStaticWarningText.Left := ScaleX(5);
oStaticWarningText.Top := oPortablePanel.Height - ScaleY(5) - ScaleY(15);
oStaticWarningText.Width := oPortablePanel.Width - ScaleX(10);
oStaticWarningText.Height := ScaleY(15);
oStaticWarningText.Anchors := [akLeft, akBottom, akRight];
oStaticWarningText.WordWrap := True
oStaticWarningText.Font.Color := clRed;
oStaticWarningText.Font.Style := [fsBold];
oStaticWarningText.Caption := 'Please launch the Installer as Administrator for static installations.';
oStaticPanel.Enabled := False;
oStaticChoice.Enabled := False;
oStaticText.Enabled := False;
oStaticChoice.Checked := False;
oPortableChoice.Checked := True;
end else begin
oStaticChoice.Checked := True;
oPortableChoice.Checked := False;
end;
Result := oPage;
end;
procedure InitializeWizard;
var
oPortablePage: TWizardPage;
begin
oPortablePage := CreatePortablePage();
end;
// ------------------------------------------------------------------------------------------------------------------ //
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := False;
if ((not IsPortablePagePortableChoiceChecked()) and (PageID = wpSelectDir)) then begin
Result := True;
end
end;
// ------------------------------------------------------------------------------------------------------------------ // // ------------------------------------------------------------------------------------------------------------------ //
function PrepareToInstall(var NeedsRestart: Boolean): String; function PrepareToInstall(var NeedsRestart: Boolean): String;
var var