Inno Setup, APP start When windows start - inno-setup

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.

Related

The correct way to include registry, custom message and code files using Inno Setup

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.

Inno Setup: Function to select a component

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".

Inno: Write User and Serial to Registry

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;

Add installation type, maintain the predefined ones

I'd like to add an own installation type into an Inno setup project, while keeping the original ones (Full, Compact and Custom). The problem is, when I create the [Types] section, these installation types are lost and I have to redefine them.
If this is not possible, okay then, let's redefine them. But I'd like to use the original language constants from the .isl files. I haven't found any option, how to use [Message]-like declarations as constants in [CustomMessage] way (e. g. {cm:LaunchProgram}) in the Types' Description parameter. Is there any option, how to do this?
Here is how you can do it, using [CustomMessages]
[CustomMessages]
FullInstall=Full installation
CompactInstall=Compact installation
CustomInstall=Custom installation
[Types]
Name: "full"; Description: "{cm:FullInstall}"
Name: "compact"; Description: "{cm:CompactInstall}"
Name: "custom"; Description: "{cm:CustomInstall}"; Flags: iscustom
Here is how you can do it using [Messages] values.
[Types]
Name: "full"; Description: "{code:FullInstall}"
Name: "compact"; Description: "{code:CompactInstall}"
Name: "custom"; Description: "{code:CustomInstall}"; Flags: iscustom
[Code]
function FullInstall(Param : String) : String;
begin
result := SetupMessage(msgFullInstallation);
end;
function CustomInstall(Param : String) : String;
begin
result := SetupMessage(msgCustomInstallation);
end;
function CompactInstall(Param : String) : String;
begin
result := SetupMessage(msgCompactInstallation);
end;

How to automatically determine the path of previous installation using Inno Setup

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.

Resources