During my inno installation I'm trying to write the username and serial to the registry and I get the following error during compile:
Invalid prototype for 'RegisteredUser'
Chunk from Inno
[Code]
function RegisteredUser(): String;
begin
Result := 'test';
end;
[Registry]
Root: HKLM; Subkey: "SOFTWARE\Platform\Brand"; ValueType: string; ValueName: "RegisteredUser"; ValueData: {code:RegisteredUser};
Any ideas?
Or if I can create the registry directly in [Code] that would work also
Thanks
Apparently in inno-setup the function called by {code:block} must be a single string parameter function (even if you do not use it.
function RegisteredUser(Param: String): string;
begin
Result := SerialPage.Values[0];
end;
Related
This might sound like a stupid question. At the moment I have created three files:
AutoBackupSettingsPage
AutoBackupSettingsPage_CustomMessages
AutoBackupSettingsPage_Registry
The first file has a [Code] section at the top, followed by the handlers and custom page for my Automatic Backups feature.
The second file file has a [CustomMessages] section at the top followed by all the appropriate custom messages.
The third file has a [Registry] section at the top followed by all the registry key definitions.
At the moment, I am using #include like this (code snipped):
[Registry]
#include ".\AutoBackupSettingsPage_Registry.iss"
[CustomMessages]
#include ".\AutoBackupSettingsPage_CustomMessages.iss"
[Code]
program Setup;
{ global variables }
var
bIsUpgrading: Boolean;
dotnetRedistPath: string;
dotNetNeeded: boolean;
bDownloadHelpDocSetup: boolean;
vcRedist64BitPath: string;
vcRedist32BitPath: string;
bVcRedist64BitNeeded : boolean;
bVcRedist32BitNeeded : boolean;
bSelectTasksVisited: Boolean;
{ Download Wizard Form plugin }
#define DwinsHs_Use_Predefined_Downloading_WizardPage
#define DwinsHs_Data_Buffer_Length 65536
#define DwinsHs_Auto_Continue
#include ".\dwinshs\dwinshs.iss"
{ Auto Backup Settings Page }
#include ".\AutoBackupSettingsPage.iss"
{ Import the LoadVCLStyle function from VclStylesInno.DLL }
procedure LoadVCLStyle(VClStyleFile: String); external 'LoadVCLStyleW#files:VclStylesInno.dll stdcall setuponly';
procedure LoadVCLStyle_UnInstall(VClStyleFile: String); external 'LoadVCLStyleW#{%TEMP}\VclStylesInno.dll stdcall uninstallonly delayload';
Initially I wanted to have all the files together in one but then I came to the conclusion that it would be wrong to insert Registry and CustomMessages sections after the start of the Code section and it would confuse the system. So I kept things simple by having distinct files and including each in the right section.
Is this the right way to do this kind of thing with Inno Setup?
To make this clear, this is how it would be in context with my master ISS file:
[Setup]
[Tasks]
[Files]
[Icons]
[Run]
[UninstallRun]
[_istool]
[Registry]
[UninstallDelete]
[InstallDelete]
[Languages]
[CustomMessages]
[Dirs]
[Thirdparty]
[Code]
[CustomMessages] #
[Registry] #
[Code] #
[Code]
The ones with the # character would be the single #include file. Did not know if it would be considered bad design to break the code section like that or not?
For arguments sake, take these little chunks. They just convey the idea of what is happening when you #include a file slap bang in the middle of the [Code] section:
; Contents before here in master
; ...
; ...
[Code]
program Setup;
{ global variables }
var
bIsUpgrading: Boolean;
dotnetRedistPath: string;
dotNetNeeded: boolean;
bDownloadHelpDocSetup: boolean;
vcRedist64BitPath: string;
vcRedist32BitPath: string;
bVcRedist64BitNeeded : boolean;
bVcRedist32BitNeeded : boolean;
bSelectTasksVisited: Boolean;
; =================================
; Start of included file
[Registry]
; 32 Bit
Root: "HKLM"; \
Subkey: "Software\MeetSchedAssist\Meeting Schedule Assistant\Options"; \
ValueType: dword; \
ValueName: "BackupAtShutdownWhat"; \
ValueData: "{code:GetWhatToBackupMode|0}"; \
Flags: uninsdeletevalue; \
Check: IsNewInstall
Root: "HKLM"; \
Subkey: "Software\MeetSchedAssist\Meeting Schedule Assistant\Options"; \
ValueType: dword; \
ValueName: "BackupAtShutdownMode"; \
ValueData: "{code:GetHowToBackupMode|0}"; \
Flags: uninsdeletevalue; \
Check: IsNewInstall
[CustomMessages]
pageAutoBackupTitle=Automatic Backup
pageAutoBackupDescription=Configure automatic backup settings.
lblBackupWhat=What to backup:
radBackupWhatNone=Don't perform any backup when the program shuts down
radBackupWhatComplete=Make a complete backup when the program shuts down
radBackupWhatEssential=Only make an essential backup when the program shuts down
lblBackupMode=How to backup:
radBackupModeAuto=Perform automatically when the program is shut down
radBackupModeManual=Prompt the user when the program is shut down
lblPromptMode=Also prompt to backup at the following intervals while the application is running:
cmbPromptModeItemNever=Never prompt to backup
cmbPromptModeItemDaily=Prompt to backup everyday
cmbPromptModeItemWeekly=Prompt to backup once a week
cmbPromptModeItemMonthly=Prompt to backup once a month
lblBackupFolder=Where to backup:
[Code]
{ Constants }
const
BackupWhat_None = 0;
BackupWhat_Complete = 1;
BackupWhat_Essential = 2;
BackupMode_Automatic = 0;
BackupMode_Manual = 1;
BackupPrompt_Never = 0;
BackupPrompt_Daily = 1;
BackupPrompt_Weekly = 2;
BackupPrompt_Monthly = 3;
{ Global Variables }
var
pageAutoBackup: TWizardPage;
pnlBackupWhat: TPanel;
lblBackupWhat: TLabel;
radBackupWhatNone: TNewRadioButton;
radBackupWhatComplete: TNewRadioButton;
radBackupWhatEssential: TNewRadioButton;
lblBackupMode: TLabel;
pnlBackupMode: TPanel;
radBackupModeAuto: TNewRadioButton;
radBackupModeManual: TNewRadioButton;
lblPromptMode: TLabel;
cmbPromptMode: TNewComboBox;
lblBackupFolder: TLabel;
txtBackupFolder: TNewEdit;
btnSelectBackupFolder: TNewButton;
;====================================
; Now the master continues with the code:
{ Import the LoadVCLStyle function from VclStylesInno.DLL }
procedure LoadVCLStyle(VClStyleFile: String); external 'LoadVCLStyleW#files:VclStylesInno.dll stdcall setuponly';
procedure LoadVCLStyle_UnInstall(VClStyleFile: String); external 'LoadVCLStyleW#{%TEMP}\VclStylesInno.dll stdcall uninstallonly delayload';
{ Import the UnLoadVCLStyles function from VclStylesInno.DLL }
procedure UnLoadVCLStyles; external 'UnLoadVCLStyles#files:VclStylesInno.dll stdcall setuponly';
procedure UnLoadVCLStyles_UnInstall; external 'UnLoadVCLStyles#{app}\VclStylesInno.dll stdcall uninstallonly';
{ Importing ShowWindow Windows API from User32.DLL }
function ShowWindow(hWnd: Integer; uType: Integer): Integer; external 'ShowWindow#user32.dll stdcall';
const
{ Changed to 4.6.2 download link (see: http://msdn.microsoft.com/en-us/library/ee942965%28v=vs.110%29.aspx#redist) }
Inno Setup does not care about the order of the sections. You can even split the sections into parts and mix the parts any way you like.
The rest is just a matter of your coding style and personal preferences.
I need to implement a scripted constant to retrieve a drive of user-selected path.
I tried the code bellow, but I'm getting:
Acess violation ate adress 0043D8E0.Read of address 01CDE694
[Code]
procedure InitializeWizard;
begin
Page := CreateInputDirPage(
wpSelectDir,'Select local', 'Where will be stored?', '', False, 'New Folder');
Page.Add('Local Dserver (APP)');
Page.Add('Local Images (Storage)');
Page.Values[0] := ('F:\TEST1');
Page.Values[1] := ('G:\TEST2');
end;
function ExtractFileDrive(const FileName: string): String;
begin
Result := ExtractFileDrive(Page.Values[0]);
end;
[Run]
Filename: {code:ExtractFileDrive|0}\postgresql-9.4.5-1-windows-x64.exe
Your ExtractFileDrive scripted constant shadows the ExtractFileDrive support function. So you recursively call your ExtractFileDrive function from itself ad infinitum, until the stack overflows.
Just rename your function to anything else.
And once doing that, rename its argument, as the FileName is confusing. And also remove the scripted constant parameter in its use, as you actually do not use it.
[Code]
function GetFileDrive(Param: string): String;
begin
Result := ExtractFileDrive(Page.Values[0]);
end;
[Run]
Filename: {code:GetFileDrive}\postgresql-9.4.5-1-windows-x64.exe
I have a small problem. I need that a page is displayed when you select one or two components. But the other is not work only with a single component seems to have an effect. I leave the code that I'm working.
[Setup]
AppName=My Program
AppVerName=My Program v.1.2
DefaultDirName={pf}\My Program
[Types]
Name: full; Description: Full installation
Name: compact; Description: Compact installation
Name: custom; Description: Custom installation; Flags: iscustom
[Components]
Name: program; Description: Program Files; Types: full compact custom; Flags: fixed
Name: help; Description: Help File; Types: full
Name: readme; Description: Readme File; Types: full
Name: readme\en; Description: English; Flags: exclusive
Name: readme\de; Description: German; Flags: exclusive
[Code]
var
Page1: TWizardPage;
Procedure InitializeWizard();
begin
Page1:= CreateCustomPage(wpSelectComponents, 'Custom wizard page 1', 'TButton');
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Case PageID of
Page1.ID: Result:= not IsComponentSelected('help');
Page1.ID: Result:= not IsComponentSelected('readme\de'); // It does not work
end;
end;
A greeting and thanks in advance.
If you need to write more complex conditions, use logical operators for that. In this case you wanted to use the and operator:
Result := not IsComponentSelected('help') and not IsComponentSelected('readme\de');
Which can be read as:
Skip page if "help" component is not selected and "readme\de"
component is not selected as well. In human language it could be, skip
page if neither "help" nor "readme\de" component is selected.
Your code so can be simplified to this:
function ShouldSkipPage(PageID: Integer): Boolean;
begin
// skip the page if it's our custom page and neither "help" nor "readme\de"
// component is selected, do not skip otherwise
Result := (PageID = Page1.ID) and (not IsComponentSelected('help') and
not IsComponentSelected('readme\de'));
end;
One final note (and a possible cause of problems), beware of switching on the same identifier in case statements. Compiler should not allow you doing this but unfortunately does, e.g. this compiles:
var
I: Integer;
begin
I := 1;
case I of
1: MsgBox('Case switch 1.1', mbInformation, MB_OK);
1: MsgBox('Case switch 1.2', mbInformation, MB_OK);
end;
end;
But only the first switch value statement executes, so you'll never see the message "Case switch 1.2".
For Inno Setup,
I would like to create a checkbox Task for MyAPP Auto Start when Windows Start.
My code like below :
And, How to write the codes below - DO_Set_AutoStart_WhenWindowsStart()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Tasks]
Name: "StartMenuEntry" ; Description: "Start my app when Windows starts" ; GroupDescription: "Windows Startup"; MinVersion: 4,4;
[code]
//Do Additional Task - Auto Start when Windows Start
function NextButtonClick(CurPageID: Integer): Boolean;
var
Index: Integer;
begin
Result := True;
if CurPageID = wpSelectTasks then
begin
Index := WizardForm.TasksList.Items.IndexOf('Start my app when Windows starts');
if Index <> -1 then
begin
if WizardForm.TasksList.Checked[Index] then
MsgBox('First task has been checked.', mbInformation, MB_OK)
DO_Set_AutoStart_WhenWindowsStart();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
else
MsgBox('First task has NOT been checked.', mbInformation, MB_OK);
end;
end;
end;
You don't need to make use of the [code] section to add an automatic starting app.
There are different ways to accomplish this, for example
[icons]
Name: "{userstartup}\My Program"; Filename: "{app}\MyProg.exe"; Tasks:StartMenuEntry;
Name: "{commonstartup}\My Program"; Filename: "{app}\MyProg.exe"; Tasks:StartMenuEntry;
The difference between {userstartup} and {commonstartup}, if not obvious, is that {userstartup} affects the startup menu entry for the current user and {commonstartup} affects all the users of the target machine.
Edit
You may also use the registry to start an application. I'm adding this because the OP mentioned in comments the described method doesn't work on windows 8 (because the lack of start menu, which I forgot). I have no windows 8 at hand to test, so it's up to you to test if this works on windows 8 or not.
The Run keys in the registry exists since WinXP, so you can configure windows to auto-run a program from the installer adding something like this:
[Registry]
;current user only
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "MyProgram"; ValueData: "{app}\MyProg.exe"; Tasks:AutoRunRegistry;
;any user
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "MyProgram"; ValueData: "{app}\MyProg.exe"; Tasks:AutoRunRegistry;
Don't miss I'm also changing the Tasks parameter in the example to AutoRunRegistry.
I'm trying to create a inno setup installer that patches a previous installation but i can't manage to force my installer determine the path where my previous installation is.
I tried using the DefaultDirName={reg:HKxx\SubkeyName,ValueName|DefaultValue} feature from inno but i'm not sure what to put in the DefaultValue's place.
How can i do that?
Edit:
i tried also this part:
[Setup]
DefaultDirName={code:GetPathInstalled}
[Code]
function GetPathInstalled (Param: String): String;
var
Country: String;
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\JoWooD\Painkiller Resurrection', 'Install', Country);
end;
But when i run the installer the path is empty.
Your code should look like:
[Code]
function GetPathInstalled (Param: String): String;
var
Country: String;
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\JoWooD\Painkiller Resurrection', 'Install', Country);
Result:= Country;
end;
The return value from the RegQueryStringValue wasn't being returned as the result of the GetPathInstalled function.