I have an application version that includes a hash. For sake of the installer, I want a simple version without the hash. I have the following code which mostly works, the part in question is the Delete call which according to the documentation Deletes the specified number of characters beginning with Index from S. S is passed by reference (therefore is modified).
#define FullAppVersion "0.0.9 - abcdef012345"
#expr WriteIni("D:\\debug.txt", "Debug", "Full", FullAppVersion)
#define SimpleVersion FullAppVersion
#expr WriteIni("D:\\debug.txt", "Debug", "SimpleBefore", SimpleVersion)
#define HashPos Pos(' ', SimpleVersion)
#expr WriteIni("D:\\debug.txt", "Debug", "Pos", HashPos)
#expr Delete(SimpleVersion, HashPos)
#expr WriteIni("D:\\debug.txt", "Debug", "SimpleAfter", SimpleVersion)
However, when the above is executed, the debug looks as such:
[Debug]
Full=0.0.9 - abcdef012345
SimpleBefore=0.0.9 - abcdef012345
Pos=6
SimpleAfter=0.0.90.0.9 - abcdef012345
Delete seems to partially work by trimming from the specified position, but then additionally concatenates the entire string at the end.
Am I doing something incorrectly, or is there a glitch in the function? Using Inno Setup Compiler 5.5.5 and Inno Script Studio 2.2.1.31
Related
My installer caters for 20 partial translations. Partial translations have the bulk of the GUI in English and just certain parts in the respective languages. To acheive this with the installer I physically duplicate the default English isl file and rename the language name property to each of the twenty languages. Then Iuse those files in the installer script to add these languages to the drop-down list for the user to choose from.
What this means is that for my custom message I have to replicate them for each of the 20 languages. At the moment I am doing it manually but I wondered if this can be managed from now on using ISPP?
So we start with these custom messages:
; Automatic Backup Settings Wizard Page
English.pageAutoBackupTitle=Automatic Backup
English.pageAutoBackupDescription=Configure automatic backup settings.
English.lblBackupWhat=What to backup:
English.radBackupWhatNone=Don't perform any backup when the program shuts down
English.radBackupWhatComplete=Make a complete backup when the program shuts down
English.radBackupWhatEssential=Only make an essential backup when the program shuts down
English.lblBackupMode=How to backup:
English.radBackupModeAuto=Perform automatically when the program is shut down
English.radBackupModeManual=Prompt the user when the program is shut down
English.lblPromptMode=Also prompt to backup at the following intervals while the application is running:
English.cmbPromptModeItemNever=Never prompt to backup
English.cmbPromptModeItemDaily=Prompt to backup everyday
English.cmbPromptModeItemWeekly=Prompt to backup once a week
English.cmbPromptModeItemMonthly=Prompt to backup once a month
English.lblBackupFolder=Where to backup:
English.btnButtonBrowse=Browse ...
And we want to replicate them for the following languages identifiers:
Amharic
Aukan
Cebuano
Filipino
Gujarati
Gun
HaitianCreole
Lingala
Malagasy
Maltese
Punjabi
Saramaccan
Sesotho
Setswana
Sranantongo
Swahili
Tamil
Tsonga
Twi
Zulu
I know I don't need to add the custom messages because the installer would default to English, but then I get the barage of compiler warnings about missing message definitions.
The preprocessor has two mechanisms how to repeat some code, both having advantages and disadvantages.
User defined procedures
With the User defined procedures, the code that you want to repeat is a way more readable – you basically use the same syntax as if you write a normal script (even syntax highlighting will work in editors), you just use {#Var} syntax to inject the variable parts.
There's virtually no limit to how long the repeated code can be long.
But the code to cause the code to repeat is clumsier, as the procedures cannot take arguments, so you have to pass the variable parts via "global variables". But in your case, with a single parameter and no recursion, it's not a big limitation.
#sub DefaultMessages
{#Lang}.pageAutoBackupTitle=Automatic Backup
{#Lang}.pageAutoBackupDescription=Configure automatic backup settings.
{#Lang}.lblBackupWhat=What to backup:
; ...
#endsub
#define Lang
#expr Lang = "German"
#expr DefaultMessages
#expr Lang = "French"
#expr DefaultMessages
; ...
If you prefer, you can put the variable assignment and procedure call to the same line using a sequential evaluation operator (a comma):
#define Lang
#expr Lang = "German", DefaultMessages
#expr Lang = "French", DefaultMessages
; ...
User defined functions
User defined functions can take parameters, so from a programming perspective, they are cleaner – and allow a recursion (not relevant in this case).
But the code is not very readable. And there's an internal preprocessor stack limit, which makes the solution not scalable.
#define DefaultMessages(Lang) \
Lang + ".pageAutoBackupTitle=Automatic Backup" + NewLine + \
Lang + ".pageAutoBackupDescription=Configure automatic backup settings." + NewLine + \
Lang + ".lblBackupWhat=What to backup:" + NewLine \
; ...
#emit DefaultMessages("German")
#emit DefaultMessages("French")
; ...
For another example, that shows implementing the same functionality using both these approaches, see:
Inno Setup - Recurse sub directories without creating those same sub directories
I am adding this answer just so that users are aware of a better approach to my situation.
I was recently told this (quite by chance as my question was a different one) on the Inno Setup Support channel:
It loads the MessageFiles in order, followed by the messages in the
script. Last one wins.
And prefixed values win over un-prefixed values within the script as
well.
So you should put all your English defaults into an .isl file that is
listed before the language-specific .isl file. Anything not specified
in the real language file will use the defaults from the previous
files.
Or alternatively if you do not want to use .isl files for your custom
messages, then you can specify your English defaults without prefix
and your actual translations with the appropriate prefix directly in
your script, omitting anything not yet translated. Again, anything
that's missing a language-specific-prefixed value will default back
to the un-prefixed value.
If you do both things, then anything in the script (prefixed or not)
will always override anything in the .isl files.
So I simplified my custom messages file:
[CustomMessages]
; ==================================================================
; These are the default custom messages.
; They are used by:
; - Amharic
; - Aukan
; - Cebuano
; - English
; - Filipino
; - Gujarati
; - Gun
; - HaitianCreole
; - Lingala
; - Malagasy
; - Maltese
; - Punjabi
; - Saramaccan
; - Sesotho
; - Setswana
; - Sranantongo
; - Swahili
; - Tamil
; - Tsonga
; - Twi
; - Vietnamese
; - Zulu
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:
All language prefixed translations follow in the same file. Using this approach I don't actually need to use the #sub / #endsub mechanism after-all.
How to append AppVersion to setup.exe file?
In other words, how to make output filename as sample-setup-1.4.2.0.exe?
[Setup]
AppName= {#GetStringFileInfo("Sample.exe", "ProductName")}
AppVersion= {#GetStringFileInfo("Sample.exe", "FileVersion")}
OutputBaseFilename=setup
Two valuable lessons are;
Lesson 1: Inline function should be used as {#FunctionName(...)}
Lesson 2: variables in [Setup] field are called by using SetupSetting function.
With above information, we can make sample-setup-1.0.0.0 as below;
OutputBaseFilename=sample-setup-{#SetupSetting("AppVersion")}
Likewise, we can append datetime;
OutputBaseFilename=sample-setup-{#SetupSetting("AppVersion") + GetDateTimeString('dd-mm-yyyy hh-nn-ss', '-', ':')}
Node.js ver: 9.2
Oracledb driver ver: 2.0.15
I have written an anonymous PL/Sql procedure with declaration, execution and exception sections of 200 lines of coding.
This runs perfectly fine when running directly on Oracle server or using any tool that can run it. However, running from within the .js file gives an error:
"detailed_message":"ORA-06550: line 1, column 3681:\nPL/SQL: ORA-00905: missing keyword\nORA-06550: line 1, column 3467:\nPL/SQL: SQL Statement ignored\nORA-06550: line 1, column 3736:\nPLS-00103: Encountered the symbol \"ELSE\" when expecting one of the following:\n\n ( begin case declare end exception exit for goto if loop mod\n null pragma raise return select update while with\n
Since the code runs fine on the server directly, I would not suspect any issues with the procedure itself. And I also have another anonymous procedure with less than 100 lines of code seems to run fine from .js file.
I would like to know if there is any limitations with the db driver running such a long procedure. (I would not want to store this procedure in the db either)
There's no artificial limit on the PL/SQL block size in node-oracledb.
Check your syntax, e.g. quote handling. Note the current examples use backticks.
If you're concatenating quoted strings together, make sure each string ends or begins with whitespace:
"BEGIN " +
"FORALL ... " +
...
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 get this exception error whenever I want to write data to a firebird db:
No mapping for the Unicode character exists in the target multi-byte code page
I tried to change the string in my write-function to UnicodeString, but I still get the same error.
I have 2 computers:
Delphi XE2, with Intraweb 12 (12.2.25)
Delphi XE6 with Intraweb 14 (14.0.32)
Everything works fine on the IW12 PC, but I have these strange problems in my application on the IW14 computer.
I'm not doing any special string manipulations, only simple read/write to the DB.
If i understand it correctly, this is a Delphi error and not the intraweb's. How can I make it go away?
here is a simple write example to an IBX ibTable that doesn't work :
With ibTable Do begin
Open;
Try
Append;
Post; // <<--- error when try to Post
Finally
Close;
End;//Try