GetComputerNameString Inno Setup - inno-setup

I have a line of text in my Inno Setup file that is:
TextBox.Text := GetComputerNameString();
to get the computers name. I'm getting this error when trying to go through the setup wizard once it's built:
Do I have to do some sort of code setup (like registering an external function or something) to call this function or should I just be able to call it since it's built in?

You declare a variable as a global variable
[code]
var
glbComputerName String;
...
step by 1 function
glbComputerName := GetComputerNameString();
TextBox.Text := glbComputerName;
...
step by 2 function
//glbComputerName use...
MsgBox( 'Computer Name :' + glbComputerName, mbError, MB_OK );

Related

How to set my own variable in [Setup] and read it from [Code]

I'm trying to create a script in Inno Setup to pull files from a GitHub repository, extract it, and write it to a directory defined in the [Setup] section.
[Setup]
MyVariable={userappdata}\MetaQuotes\Terminal\{#MyAppName}
[Code]
procedure CurStepChanged(CurStep: TSetupStep);
begin
// Copy the selected files to the selected directory
if not FileCopy(Output + '\file1.txt', MyVariable + '\file1.txt', False) then
begin
MsgBox('Failed to copy file1.txt to the selected directory.', mbError, MB_OK);
Abort();
end;
if not FileCopy(Output + '\file2.txt', MyVariable + '\file2.txt', False) then
begin
MsgBox('Failed to copy file2.txt to the selected directory.', mbError, MB_OK);
Abort();
end;
end;
Obviously, this won't compile because MyVariable hasn't been defined in the Pascal script. Only, I'm not sure how to reference the value in [Setup]. Or am I going about this in the wrong way?
Well, you can read the [Setup] section directives with SetupSetting preprocessor function:
How to read a [Setup] parameter in the Pascal code?
But you cannot invent your own new directives.
But you can either:
Use preprocessor variable using #define directive (the way you already use it for MyAppName):
#define MyVariable "{userappdata}\MetaQuotes\Terminal\" + MyAppName
It does not matter where you place the #define as long as it it before you use the variable.
Use it like this in the Pascal Script:
ExpandConstant('{#MyVariable}\file1.txt')
The ExpandConstant is to expand the {userappdata}.
Use Pascal Script constant:
[Code]
const
MyVariable = '{userappdata}\MetaQuotes\Terminal\{#MyAppName}';
Use it like any other Pascal Script variable/constant.
ExpandConstant(MyVariable) + '\file1.txt'

Use two/multiple selected directories from custom page in Files section

I need create custom page of two destination.
I've done:
#define MyAppName "TESTPROG"
[Setup]
AppName={#MyAppName}
DefaultDirName=C:\test\{#MyAppName}
DefaultGroupName={#MyAppName}
[Code]
var
Page: TInputDirWizardPage;
DataDir: String;
procedure InitializeWizard;
begin
Page := CreateInputDirPage(wpWelcome,
'Select Personal Data Location', 'Where should personal data files be stored?',
'Personal data files will be stored in the following folder.'#13#10#13#10 +
'To continue, click Next. ' +
'If you would like to select a different folder, click Browse.',
False, 'New Folder');
Page.Add('Local APP');
Page.Add('Local Storage');
Page.Values[0] := ('C:\My Program');
Page.Values[1] := ('D:\My Program');
DataDir := Page.Values[0];
end;
I need to know how and where I set DefaultDirName with Page.Values[0] and Page.Values[1]
I need it because some part of my files will be in a folder and others in other folder.
For example:
[Files]
Source: C:\TEST\DLL1.bat; DestDir: Page.Values[0]\sys1;
Source: C:\TEST\DLL2.bat; DestDir: Page.Values[1]\sys2;
Use a scripted constant:
[Files]
Source: C:\TEST\DLL1.bat; DestDir: "{code:GetDir|0}\sys1"
Source: C:\TEST\DLL2.bat; DestDir: "{code:GetDir|1}\sys2"
[Code]
var
Page: TInputDirWizardPage;
function GetDir(Param: string): string;
begin
Result := Page.Values[StrToInt(Param)];
end;
procedure InitializeWizard;
begin
Page := CreateInputDirPage(...);
...
end;
If you want to use one of the (the first) paths from the TInputDirWizardPage instead of the path from "Select Destination Location" page, you have three options.
Disable the "Select Destination Location" page using DisableDirPage directive:
DisableDirPage=yes
Copy the path from the TInputDirWizardPage to the hidden "Select
Destination Location" page, when the user presses Next button:
var
Page: TInputDirWizardPage;
function InputDirPageNextButtonClick(Sender: TWizardPage): Boolean;
begin
{ Use the first path as the "destination path" }
WizardForm.DirEdit.Text := Page.Values[0];
Result := True;
end;
procedure InitializeWizard();
begin
Page := CreateInputDirPage(...);
...
Page.OnNextButtonClick := #InputDirPageNextButtonClick;
end;
To complement that you may also consider copying the initial WizardForm.DirEdit to your custom box. This way you make sure that 1) on re-install/upgrade, the previously selected value is reused; 2) /DIR command-line switch works. For that see How to make Inno Setup /DIR command line switch work with custom path page.
Replace all uses of the {app} constant with {code:GetDir|0}.
Make Inno Setup not create the {app} path using CreateAppDir directive:
CreateAppDir=no
(this implies DisableDirPage=yes).
And have the uninstall files be stored in the first path using UninstallFilesDir directive:
UninstallFilesDir={code:GetDir|0}
Contrary to 1), with this approach the previous installation path won't get reused for the later upgrade/re-install. To implement that see Inno Setup Prompt user for a folder and store the value.
Do not use the CreateInputDirPage, but rather add a second path input box on the "Select Destination Location" page (SelectDirPage).

WizardForm.DirEdit.Text not updating properly. Inno setup

I am trying to set the path in the 'choose install directory' form using INNO setup. Here is my code
procedure CurPageChanged(pageID: Integer);
var
sInstallDir: String;
begin
// Default install dir is the IIS install path
if (pageID = wpSelectDir) then begin
sInstallDir := GetIISInstallPath + '\MyFolder';
Log('GetIISInstallPath: '+ GetIISInstallPath);
Log('sInstallDir: ' + sInstallDir);
WizardForm.DirEdit.Text := sInstallDir;
end;
end;
The problem I am having is that 'GetIISInstallPath' returns me 'c:\inetpub\wwwroot and that is what I see in the WizardForm. It seems to not add the MyFolder bit.
I printed out the involved variables and they all have the correct value.
sInstallDir shows up as 'C:\inetpub\wwwroot\MyFolder' but it does not show in the text field. It shows (as mentioned) only 'C:\inetpub\wwwroot'.
Please advise.
Thank You
Your code works fine for me but, can I suggest you to use
[Setup]
...
DefaultDirName={code:GetDefaultDirName}
[code]
...
function GetDefaultDirName(): String;
begin
Result := GetIISInstallPath + '\MyFolder';
end;
Doing this the "GetIISInstallPath + \MyFolder" will be your default directory

InnoSetup - Set DefaultDirName at runtime

I have an application that needs to allow for up to three simultaneous installations on the same machine.
For some reason, the following code behaves as if UsePreviousAppDir is set to yes. The second time I install the app, the path ends up mangled.
The value I want to see is
C:\Our App\install_x where x corresponds to the user's selection.
It works the first time, but the second run results in something like this:
C:\Our App\install_x\install_y, where x corresponds to the value selected with the first installation and y corresponds to the value selected during this installation.
The install version is a radio button selection grabbed from the first screen in the installer. How do I eliminate this issue?
Setup section:
[Setup]
AppName=Our App
AppId=Our App
AppVerName=Our App Version(CM)
DefaultDirName=C:\Our App
DefaultGroupName=Our Group Name
OutputDir=..\
OutputBaseFilename=mm_setup
DisableStartupPrompt=yes
Compression=zip
UsePreviousAppDir=no
VersionInfoDescription=Our App Setup
CreateUninstallRegKey=no
DirExistsWarning=no
And the method where I set the install version:
procedure gSetVersion;
begin
if gVersionPage.SelectedValueIndex = 0 then
begin
gInstallArea := 'install_a';
end
else if gVersionPage.SelectedValueIndex = 1 then
begin
gInstallArea := 'install_b';
end
else if gVersionPage.SelectedValueIndex = 2 then
begin
gInstallArea := 'install_c';
end
WizardForm.DirEdit.Text := WizardDirValue + '\' + gInstallArea;
end;
Solved the problem via the following hack. Not sure why it was necessary to manually edit the string when the `UsePreviousAppDir=no' was set, but this works
procedure gSetVersion;
var
installVersionIndex: Integer;
installDir: String;
begin
case gVersionPage.SelectedValueIndex of
0: gInstallArea := 'install_a';
1: gInstallArea := 'install_b';
2: gInstallArea := 'install_c';
end
//Set the default installation folder.
//This is necessary because InnoSetup intermittently
//ignores the 'UsePreviousAppDir=no' [Setup] directive
//and because the 'DefaultDirName' directive gets populated
//prior to the user selecting the install version
installVersionIndex := Pos('install_', WizardDirValue);
installDir := WizardDirValue;
if installVersionIndex > 0 then
begin
Delete(installDir, installVersionIndex, 20);
end
WizardForm.DirEdit.Text := installDir + '\' + gInstallArea;
end;

How to set automaticly DefaultDirName for previous Inno Setup installation?

my previous installation (A) in Inno Setup has AppID={{8ADA0E54-F327-4717-85A9-9DE3F8A6D100}.
I have another installation (B) with different AppID and I want to install it into the same directory as installation (A).
How do I get automaticly DefaultDirName? I don't want to use the same AppID, because when I uninstall the installation (B) and installation (A) stays installed, it will delete AppID string from registry (installation (A) string).
Can you help me, please?
You'll probably need some code to do what you want. You'll also need a way to find the installation directory of Application A. Here's some code that I've used
[Setup]
DefaultDirName={code:GetDefaultDir}
[Code]
function GetDefaultDir(def: string): string;
var
sTemp : string;
begin
//Set a defualt value so that the install doesn't fail.
sTemp := ExpandConstant('{pf}') + '\MyCompany\MyAppA';
//We need to get the current install directory.
if RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\MyCompany\Products\MyAppNameA',
'InstallDir', sTemp) then
begin
//We found the value in the registry so we'll use that. Otherwise we use the default
end;
Result := sTemp;
end;
I developed the following code to find the installation directory based on AppID. It accommodates per-user registry entries as well as those for the entire machine. It has been tested on Windows 7 Enterprise on a domain and in a Virtual PC XP Professional machine:
[code]
const
PreviousAppID = '8ADA0E54-F327-4717-85A9-9DE3F8A6D100';
AppFolder = 'SomeFolder';
UninstallPath = 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{'
+ PreviousAppID + '}_is1';
// Some posts have 'InstallDir', but I have never observed that
InstallKey = 'InstallLocation';
function GetDefaultDir( Param: String ) : String;
var
UserSIDs: TArrayOfString;
I: Integer;
begin
// Check if the current user installed it
if RegQueryStringValue( HKEY_CURRENT_USER, UninstallPath,
InstallKey, Result ) then
// Current user didn't install it. Did someone else?
else if RegGetSubkeyNames( HKEY_USERS, '', UserSIDs ) then begin
for I := 0 to GetArrayLength( UserSIDs ) - 1 do begin
if RegQueryStringValue( HKEY_USERS, UserSIDs[I] + '\' + UninstallPath,
InstallKey, Result ) then break;
end;
end;
// Not installed per-user
if Result = '' then begin
// What about installed for the machine?
if RegQueryStringValue( HKEY_LOCAL_MACHINE, UninstallPath,
InstallKey, Result ) then
// Doesn't appear to be installed, as admin default to Program Files
else if IsAdminLoggedOn() then begin
Result := ExpandConstant('{pf}\') + AppFolder;
// As non-admin, default to Local Application Data
end else begin
Result := ExpandConstant('{localappdata}\') + AppFolder;
end;
end;
end;

Resources