Retrieve environment variable using RegQueryStringValue in Inno Setup - inno-setup

I am trying to retrieve an environment variable during installation using RegQueryStringValue,
I am using the following code
[Setup]
DefaultGroupName="{code:GetPath}"
[Code]
function GetPath(Value: String): String;
var
OrigPath: string;
begin
if RegQueryStringValue(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'GCC', OrigPath) then
Result := OrigPath;
end;
But the installer gives me an error during installation,
Can someone tell me why or what I can use instead?

In the case of this question, you're trying to use DefaultGroupName instead of DefaultDirName which is causing the errors.

Related

Hardcode startup switches into INNO Setup script and retrieve them in [code] in InnoIDE

When I compile and then run my Inno script, I want to parse hard coded command line switches. So, instead of running my script as c:\myInstall.exe /myswitch I want to run it via IDE and have this switch included at the start here
With this code, I want to retrieve this switch in ParamStr(x)
function MyParams(param: String): string;
begin
MsgBox(ParamStr(3), mbError, MB_OK);
Result := MyParameter;
end;
{Parameter Detection--end}
function InitializeSetup(): Boolean;
begin
MyParams('XXX');
end;
I found a tool, which does this for you - you can set DEBUG variables if you use
Inno Script Studio

Inno Script: Skip password if the application is already installed

I am trying to create an Inno Setup installer that will require a password from the user if the application has never been installed on the local machine.
I have the script that gets a password, and I have a Code section that checks for the existence of the uninstall registry key, but being new to Inno Setup scripting, I'm not sure how to link the two parts together.
Can anyone explain how to forgo the user from entering a password if the app is already installed?
Here is the (test) script...
#define myAppID "2B7D6E48-74A8-4070-8BA7-621115D6FD00"
[Setup]
AppId={{{#myAppID}}
Password=123456
[Code]
function checkForPreviousInstall(): Boolean;
begin
Result := False;
if RegKeyExists(HKEY_LOCAL_MACHINE,'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{#myAppId}_is1') or
RegKeyExists(HKEY_CURRENT_USER, 'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{#myAppId}_is1') then
begin
MsgBox('The application is installed already.', mbInformation, MB_OK);
Result := True;
end;
end;
Skip the password page, if the application is installed already.
Use ShouldSkipPage event function:
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := False;
if (PageID = wpPassword) and checkForPreviousInstall then Result := True;
end;

Perform DeleteFile only on NEW installation [duplicate]

My InnoSetup script opens a web page (with the user's default browser) at the end of the install process:
[Run]
Filename: http://example.com; Flags: shellexec
However, I'd like the web page to not be opened if the app already exists, i.e., if the user is installing a new version of the program. The web page should only be opened after the initial install. (I assume it's worth mentioning that the install includes an AppID, obviously, and enters values in the registry beside installing files.)
Thank you, as always -- Al C.
Yes, this is easy to do with scripting.
Just write
[Run]
Filename: "http://example.com"; Flags: shellexec; Check: NotAnUpdate
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpInstalling then
IsUpdate := FileExists(ExpandConstant('{app}\TheFileNameOfMyApp.exe'));
end;
function NotAnUpdate: Boolean;
begin
result := not IsUpdate;
end;
The answer by #AndreasRejbrand won't work, if user chooses to install the executable to a different location than the last time.
You can query installer-specific Inno Setup registry keys:
#define AppId "your-app-id"
#define SetupReg \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\" + AppId + "_is1"
#define SetupAppPathReg "Inno Setup: App Path"
[Setup]
AppId={#AppId}
...
[Run]
Filename: "https://www.example.com/"; Flags: shellexec; Check: not IsUpgrade
...
[Code]
function IsUpgrade: Boolean;
var
S: string;
begin
Result :=
RegQueryStringValue(HKLM, '{#SetupReg}', '{#SetupAppPathReg}', S) or
RegQueryStringValue(HKCU, '{#SetupReg}', '{#SetupAppPathReg}', S);
end;
For an example how to use IsUpgrade in [Code] section, see
Excludes part of Code section in ssPostInstall step if installation is update in Inno Setup
Check this if your "AppId" contains a left-curly-bracket:
Checking if installation is fresh or upgrade does not work when AppId contains a curly bracket

Execute different BLOCK of commands in Inno Setup Run section based on Windows version

I know there is already question Execute different command in Inno Setup Run section based on Windows version with very good answer.
My question is how to perform different blocks of commands for different target Windows versions. My problem is that I have ~10-15 commands that need to perform if target version is Windows 7 and the ~same amount of different commands for Windows 8 or above.
Is it possible to avoid the need to add ; OnlyBelowVersion: 6.2 after each command needed for first case and ; MinVersion: 6.2 after each command in the second block?
I know there is preprocessor conditions "#if", #else and #endif but that of course works only at compilation time
The question and answers Determine Windows version in Inno Setup although may look similar to this question are NOT answering it. I know how to determine Windows version in Inno Setup. I also know about those ; MinVersion: 6.2 and ; OnlyBelowVersion: 6.2 options. I am asking if it is possible to specify a block of commands (10-15 commands) and apply that option to entire block, not to each and every command individually.
The goal is not to avoid "cryptic version numbers" but to avoid repeating the same condition many times. And to avoid risk of forgetting it when block will grow over the time.
The solution that I found so far is to use CurStepChanged procedure:
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
if IsWindows8OrLater() then
MsgBox('Running on Windows 8 Or Later', mbInformation, MB_OK)
{ 15 comands or call of W8-specific procedure goes here }
else begin
MsgBox('Running on Windows 7', mbInformation, MB_OK);
{ 15 comands or call of W7-specific procedure goes here }
end;
end;
But it looks a bit ugly to me...
There are no block-control features in the .iss file.
All you can do, to avoid repeating the cryptic version numbers, is to define a preprocessor variable like:
#define Windows8AndNewer "MinVersion: 6.2"
#define Windows7AndOlder "OnlyBelowVersion: 6.2"
[Run]
Filename: "Windows8-Command1.exe"; {#Windows8AndNewer}
Filename: "Windows8-Command2.exe"; {#Windows8AndNewer}
Filename: "Windows7-Command1.exe"; {#Windows7AndOlder}
Filename: "Windows7-Command2.exe"; {#Windows7AndOlder}
The only other way is to reimplement the [Run] section in the [Code] using the Exec function:
procedure Run(FileName: string);
var
ResultCode: Integer;
begin
Exec(FileName, '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
{ some error checking }
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
if GetWindowsVersion() >= $06020000 then
begin
Log('Running on Windows 8 or later');
Run('Windows8-Command1.exe');
Run('Windows8-Command2.exe');
end
else
begin
Log('Running on Windows 7 or older');
Run('Windows7-Command1.exe');
Run('Windows7-Command2.exe');
end;
end;
end;

Can Inno Setup respond differently to a new install and an update?

My InnoSetup script opens a web page (with the user's default browser) at the end of the install process:
[Run]
Filename: http://example.com; Flags: shellexec
However, I'd like the web page to not be opened if the app already exists, i.e., if the user is installing a new version of the program. The web page should only be opened after the initial install. (I assume it's worth mentioning that the install includes an AppID, obviously, and enters values in the registry beside installing files.)
Thank you, as always -- Al C.
Yes, this is easy to do with scripting.
Just write
[Run]
Filename: "http://example.com"; Flags: shellexec; Check: NotAnUpdate
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpInstalling then
IsUpdate := FileExists(ExpandConstant('{app}\TheFileNameOfMyApp.exe'));
end;
function NotAnUpdate: Boolean;
begin
result := not IsUpdate;
end;
The answer by #AndreasRejbrand won't work, if user chooses to install the executable to a different location than the last time.
You can query installer-specific Inno Setup registry keys:
#define AppId "your-app-id"
#define SetupReg \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\" + AppId + "_is1"
#define SetupAppPathReg "Inno Setup: App Path"
[Setup]
AppId={#AppId}
...
[Run]
Filename: "https://www.example.com/"; Flags: shellexec; Check: not IsUpgrade
...
[Code]
function IsUpgrade: Boolean;
var
S: string;
begin
Result :=
RegQueryStringValue(HKLM, '{#SetupReg}', '{#SetupAppPathReg}', S) or
RegQueryStringValue(HKCU, '{#SetupReg}', '{#SetupAppPathReg}', S);
end;
For an example how to use IsUpgrade in [Code] section, see
Excludes part of Code section in ssPostInstall step if installation is update in Inno Setup
Check this if your "AppId" contains a left-curly-bracket:
Checking if installation is fresh or upgrade does not work when AppId contains a curly bracket

Resources