In Inno Setup one can access texts from the language files e.g. the following way (where CreateDesktopIcon is the text entry to look for):
[Tasks]
Name: "TaskDesktopIcon"; Description: "{cm:CreateDesktopIcon}"; Flags:
My question is how to access texts from the language files from the code section of the Inno Setup script?
I have tried the following, but the compiler will not accept the syntax:
[code]
var
pageAutoLogon: TWizardPage;
procedure CreateAutoLogonPage;
begin
pageAutoLogon := CreateCustomPage(wpSelectTasks, "{cm:AutoLogonCredentialsTitle}", "{cm:AutoLogonCredentialsDescription}");
...
Any help is appreciated!
You need to call ExpandConstant (or ExpandConstantEx) function to evaluate a constant in script code. Like this way for instance:
procedure CreateAutoLogonPage;
begin
pageAutoLogon := CreateCustomPage(wpSelectTasks, ExpandConstant('{cm:AutoLogonCredentialsTitle}'), ExpandConstant('{cm:AutoLogonCredentialsDescription}'));
...
end;
You can use the CustomMessage() function to retrieve the values from the [CustomMessages] section.
pageAutoLogon := CreateCustomPage(wpSelectTasks, CustomMessage('AutoLogonCredentialsTitle'), CustomMessage('AutoLogonCredentialsDescription'));
For normal [Messages], you can use the SetupMessage() with one of the enum values.
Related
I am currently extracting the Pin List - Pin Names in Altium Designer that uses DelphiScript (not Delphi). DelphiScript and Delphi has differences and I believe one of them is the file I/O component. According to the Altium Docs for DelphiScript, only text files and csv files can be produced. In producing an output file .csv, saving is as easy as throwing text that are comma delimited and then saving with an extension '.csv'. My problem now is how to create a .xls file without importing and/or downloading plugins/extensions like eDocEngine VCL, LibXL, TQExport4Xlsx.
Tried declaring TBook, TSheet, TgtXLSEngine or other ways to create the spreadsheet but error says it is an undeclared identifier.
Do you guys have any idea?
Report Writer Code Snippet:
Procedure BeginReportPinList(AFilename: String);
Begin
gv_FileName := AFilename + '.csv';
AssignFile(gv_FileReport, gv_FileName);
Rewrite(gv_FileReport);
End;
Procedure WriteReportDUT(AReport : String);
Begin
WriteLn(gv_FileReport, Format('%s', [AReport]));
End;
Procedure EndReport(Dummy : Boolean);
Begin
CloseFile(gv_FileReport);
End;
String Parser Code Snippet that calls above procedures:
if dutlistX.Count = 1 then
Begin
PinFilename := copy(gv_Board.FileName, 1, Pos('-05', gv_Board.FileName)-1) + '-14';
BeginReportPinList(PinFilename);
For I := 0 To finalreport.Count - 1 Do
Begin
WriteReportDUT(finalreport[I]);
End;
EndReport(0);
End;
As was mentioned in comments by #Ken White, it is very difficult to do this without third-party components.
As far as I know, XSL file has a structure of Compound File Binary Format. This type of files consisting of blocks and streams that You can manipulate. I have used this third-party software to parse such file type (actually SchDoc, but not XLS), check this question. OpenMCDF can do a trick if You have Altium running with .NET platform, like 16 version do, for example. In addition, You may use the specification of this file format based on CFB.
It is very noticeable, that some other filetypes of Altium is using that CFB file format, so it might be useful to know about OpenMCDF. I believe that XLS can be created in much handy way, than this one, but it is useful to know, how to deal with such data containers, as XLS, or SchDoc, et cetera.
I would like to specify that the Wizard Pages do not open in the middle of the screen by default i.e. to position them slightly off-centre using x,y coordinates (or a similar offset). This is because I call another program that also opens in the middle of the screen, obscuring the progress page. If I could open all Wizard pages offset to the left or top, for example, it would mean both windows would be visible at the same time, without having to reposition them. Is this possible and, if so, how could it be done?
Just offset the WizardForm.Left and WizardForm.Top as needed:
procedure InitializeWizard();
begin
WizardForm.Left := WizardForm.Left - ScaleX(320);
WizardForm.Top := WizardForm.Top - ScaleY(160);
end;
Or maybe:
procedure InitializeWizard();
begin
WizardForm.Left := WizardForm.Left div 2;
WizardForm.Top := WizardForm.Top div 2;
end;
It's been a while since I've used INNO, but I believe you can do this with some custom code in the [CODE] section. You'd have to create a overload to modify WizardForm..Left and WizardForm..Top as appropriate in InitializeWizard().
Check CodeDlg.iss and CodeClassess.iss in the Examples folder, and possibly the rest in there, for examples (sic) and details on how to properly set up the [CODE] section.
Useful docs: http://www.jrsoftware.org/ishelp/index.php?topic=scriptclasses
In my Setup I don't want use the standard Language Dialog form.
Instead, I want to add a combobox to the Welcome page of my Inno Setup to do the same job made by the Language Dialog, so that it's able to :
show all the languages included in the [Languages] section in the drop down list. So the user can select a language from this custom combobox.
apply the chosen language to the whole setup.
I know that this is not possible using the "normal way", because there are no functions available in Inno Setup to perform this job (!!!).
So that, I added a couple of functions to the Inno Setup compiler and I call them from my script:
function GetAvailableLanguages: TStringList: it is able to return the list of all the active languages (complete data), and it works fine.
procedure SetChosenLanguage(const I:integer): it should set the chosen language, and it does but up now only "partially". The language is changed for everything BUT the labels in all the Setup pages. So, button captions, message boxes, dialog boxes,... everything has the language set to the chosen one, but all the labels are still in the default (OS) language.
I tried to resolve using Refresh, Invalidate, Update, sending messages without any success. The label captions are still in the original default language.
The link below is a video showing my Test setup with the combobox and language changing. My default (OS) language is Italian. The video shows that even if I change the language, for example, to Deutsch, everything will change the language to Deustch BUT the labels.
http://screencast.com/t/SDI5VN67LFL
If someone has already resolved the problem please help me!
You would have to re-set all the labels one by one the same way the TWizardForm code initializes them to the initial language.
For example:
SelectTasksLabel.Caption := ExpandSetupMessage(msgSelectTasksLabel2);
See TWizardForm.Create code for more.
There's no easier way. The strings are copied to the Windows (Win32) controls, they won't magically learn that you have changed the language. You have to overwrite the strings with the new values.
For example the labels of the "Next" and "Back" buttons are updated with the language change, because they are always re-set, when a page is changed, from TWizardForm.SetCurPage:
procedure TWizardForm.SetCurPage(const NewPageID: Integer);
...
begin
...
BackButton.Caption := SetupMessages[msgButtonBack];
if CurPageID = wpReady then begin
NextButton.Caption := SetupMessages[msgButtonInstall];
CancelButton.Caption := SetupMessages[msgButtonCancel];
end else if ((CurPageID = wpPreparing) and PrepareToInstallNeedsRestart) or (CurPageID = wpFinished) then begin
NextButton.Caption := SetupMessages[msgButtonFinish];
CancelButton.Caption := SetupMessages[msgButtonCancel];
end else begin
NextButton.Caption := SetupMessages[msgButtonNext];
CancelButton.Caption := SetupMessages[msgButtonCancel];
end;
...
end;
But most other labels are static and are never updated, so they stay to the original language.
How can you test to see if a windows group is already setup? Can you somehow use the response from:
Exec('net.exe', 'localgroup', '', SW_SHOW, ewWaitUntilTerminated, Result);
which will list the groups to the command prompt? (I know that Result is an error code where 0 is success, just to be clear.)
Is there a way? Is there more than one way?
I haven't tested this, or had time to work out the exact process or syntax, but you could possibly use command redirection (see https://technet.microsoft.com/en-us/library/bb490982.aspx), using net localgroup as you suggested, to find the group name and output it to a text file. You could then read it into Inno Setup using LoadStringFromFile, then all you would need to do is compare the two strings.
So, having looked at this in more detail, to see if the Administrators group exists you could use:
[Run]
Filename: "{cmd}"; Parameters: "/c ""net localgroup | find /i ""Administrators"" > ""{tmp}\groupresult.txt"""""; StatusMsg: "Querying user groups..."; Flags: runhidden
[Code]
var
strGroupResult: String;
begin
LoadStringFromFile(ExpandConstant('{tmp}\groupresult.txt'), strGroupResult);
if strGroupResult = '*Administrators' then
begin
//Code to execute if group exists
...
end;
DeleteFile(ExpandConstant('{tmp}\groupresult.txt'));
end;
Note that net localgroup returns an asterisk (*) in front of the group name, so the string comparison needs to also include the asterisk.
If you need to do this before the [Run] section, you can write a similar Exec line in the [Code] section to run the same process.
I'm trying to use the silent mode of InnoSetup. I have to update the "License" key value if specified in silent mode installation.
This is how I configured the Inno file:
[INI]
Filename: define.ini; Section: "General"; Key: "License"; String: "{param:LICENSE}"; Check: WizardSilent;
It works good when the user installs the application this way:
setup.exe /SILENT /LICENSE=licensekey
The problem occurs when I want to skip the /LICENSE parameter (since it's already configured and I don't want to change this. For instance: when installing a patch kit).
Using the following way overrides "License" key on INI file and just leave it empty:
setup.exe /SILENT
How to avoid this? I just want NOT to change the "License" value in this case.
Thank you!
I can think of two options since you are using a custom parameter. Either you can define a default value for the {param} constant to be the existing value read from the same INI file:
[INI]
...; String: "{param:LICENSE|{ini:define.ini,General,License|}}"
The above statement writes to the given INI file value passed by the LICENSE command line parameter, or if it's not specified reads the same value from the same file. So it actually overwrites the value with the same value if the parameter is not specified, which is not much clean in my view.
Or, you may extend your existing Check parameter by the helper function like follows. This is the way I would prefer, since you just skip processing of the entry instead of overwriting the same value when the parameter is not specified:
[INI]
...; Check: WizardSilent and CmdLineParamExists('/LICENSE')
[Code]
function CmdLineParamExists(const Value: string): Boolean;
var
I: Integer;
begin
Result := False;
for I := 1 to ParamCount do
if CompareText(ParamStr(I), Value) = 0 then
begin
Result := True;
Exit;
end;
end;