I have a script that reads the version number from an application file. Now I need to find a way to place this number in the AppVersion directive of Inno Setup.
How can I place the return value of my function in the AppVersion directive?
Use a scripted constant:
[Setup]
AppVersion={code:GetAppVersion}
[Code]
function GetAppVersion(Param: string): string;
begin
Result := MyFunction;
end;
If the function call is costly, you should cache its value to a global variable and use the cached value in the scripted constant.
Related
I would like to write the srcexe (Should return c:\setup.exe) to a file in my application folder.
Here is what I have tried. However the file gets created but it is empty.
Maybe im running in the wrong procedure or I'm calling incorrectly.
[Code]
procedure DeinitializeSetup();
var Path : string;
begin
Path := GetEnv('srcexe');
SaveStringToFile('C:\appname\filename.txt',Path, False);
end;
The srcexe is not an "environmental variable", it's an Inno Setup constant.
To expand the constant, use the ExpandConstant function with a proper constant syntax (curly brackets).
Path := ExpandConstant('{srcexe}');
Related to Inno setup: how to replace a string in XML file?
As suggested in the answer I'm using a template xml, let's say "app.xml". I would like to replace a string in that file: "Dsn=Serverxxx" with the result of a function "DsnName" {code:DsnName} I use elsewhere in the script.
[Code]
procedure WriteAppPath;
var
FileData: String;
begin
LoadStringFromFile(ExpandConstant('{app}\app.xml'), FileData);
StringChange(FileData, 'XXXXXMARKERXXXXX', ExpandConstant('{app}'));
SaveStringToFile(ExpandConstant('{app}\app.xml'), FileData, False);
end;
I cant seem to get this to work. How would the code above look acomplishing this? And, how would it look using StringChangeEx?
I know this will probably be marked as duplicate, but I just can't figure it out.
Thanks.
I think if you look at the Inno Setup help it explains it:
http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_stringchangeex
Description:
Changes all occurrences in S of FromStr to ToStr. If SupportDBCS is True (recommended unless you require binary safety), double-byte character sequences in S are recognized and handled properly. Otherwise, the function behaves in a binary-safe manner. Returns the number of times FromStr was matched and changed.
So what you are doing is:
Reading in your text file as one long text string.
Changing all instances of Xxx with Yyy in the string.
Saving the string back to the file.
But looking here it does states:
Loads the specified binary or non Unicode text file into the specified string. Returns True if successful, False otherwise.
So this function might not be ok for you because XML files are usually Unicode.
The answer here explains.
I am relatively new to Delphi and I want to make a quick application the uses the ShellExecute command.
I want to use string values in edit boxes to add to the command line for doing the processing job outside of the application.
Everything works fine, but I get the error :
"Incompatible types: String and PAnsiChar"
I have tried to convert it using:
Variable := PAnsiChar(AnsiString(editbox.Text), but to no avail.
Can anyone assist me with this problem please.
In Delphi 7, it's a simple typecast to PChar, which is already a PAnsiChar:
PChar(YourStringVariable);
or
PChar('Some text here'); // Cast not needed; demonstration only
PChar('C:\' + AFileName); // Cast needed because of variable use
Using it with ShellExecute:
AFile := 'C:\MyDir\Readme.txt';
Res := ShellExecute(0, 'open', PChar(AFile),
nil, nil, SW_NORMAL )
How could it work fine when you cannot compile it?
You have posted too little code to be sure what is wrong, but you definitively have one typecast too much. AnsiChar is type that can store only single character and it makes no sense here.
If Variable is PAnsiChar then you should be using:
Variable := PAnsiChar(editbox.Text)
When passing filename parameters to procedures/functions, should I use TFilename or String.
If there is a difference, what is it, and what are then potential ramifications if using a String?
e.g.
procedure TForm1.OpenFile(const AFilename : String);
begin
//Open the file if it exists
...
end;
I think TFilename should be used when developing components because that way IDE can show it's property editor (TOpenDialog will be shown when clicked on ellipsis in the property inspector).
Other than this there is basically no difference which one to use. Remember that if you use TFilename you must add SysUtils to your uses clause.
The only practical difference between string and TFileName types in a plain code is in passing an argument by reference; the following code
procedure GetFileName(var FileName: TFileName);
begin
FileName:= 'abcd.abc';
end;
procedure TForm1.Button2Click(Sender: TObject);
var
S: string;
begin
GetFileName(S);
end;
does not compile with error
[DCC Error] E2033 Types of actual and formal var parameters must be identical
Maybe this is a bit too obvious, but using the string type doesn't communicate anything about the intended usage of a variable. But when you encounter a variable declared as a TFileName, there's a lot more detail communicated right there.
The same principle applys to other basic types like Integer, Cardinal, Double etc. Instead you might want to consider using aliases for these like TCustomerID, THashValue, TInterestRate, etc. as these communicate much clearer what the intended usage of these variables is.
This improves readablility, and also allows for changing the base-type when needed, without having to touch any code using the type... just a recompile and you're done (but do be carefull with binary compatibility ofcourse).
Hmm, My strong preference is for const AFilename: String;
For the reason that especially for larger projects, if you ever need to add source code from another coder, if they have used lots of custom types like TCustomerID, THashValue, TInterestRate, instead of Integer, Cardinal, Double, then you have lots of the above mentioned E2033 to resolve.
Even lots of delphi built in source code doesn't use TFileName, like:
function MatchesMask(const Filename, Mask: string): Boolean;
Furthermore if I have a variable defined like AFileName: TFileName; then its obvious its a filename & the named type doesn't add any readability for me, if anything in some cases it makes code less readable, because you have to click through to check what actual variable its derived from.
Is there a way to get local date time stamp in Inno Setup ?
The answer depends on when you need it.
Needed at the time the setup is built
Needed at the time of install.
Needed at the time the setup is built.
You will need to use ISPP which is part of the Quick Start pack.
You can use the str GetDateTimeString(str, str, str) function.
Example: #define MyDateTimeString GetDateTimeString('dd/mm/yyyy hh:nn:ss', '-', ':');
The help menu in ISTool (Also a part of the Quick Start Pack) has a good help file for ISPP functions including this one where there is a page of information on this function.
Needed at the time of install.
Although a different source, the function is also called GetDateTimeString
Then it must be in a pascal coding block.
Example:
function DateTime : String;
begin
result := GetDateTimeString('dd/mm/yyyy hh:nn:ss', '-', ':');
end;
The details of how to use it are found in the Help File.
Although both functions have the same name, the context of when they are used is important to understanding why you would get one value over another.