How to let user to browse to a file to be copied with Inno Setup - installation

I need user to browse to a file, select it, and then have this file copied from selected source to app folder.
Following this post
How to show/use the user selected app path {app} in InputDirPage in Inno Setup?
and Inno Setup documentation, i came to this piece of code:
[Files]
Source: {code:GetDBPath}; DestDir: "{app}"; Flags: confirmoverwrite uninsneveruninstall;
[Code]
var
SelectDBPage: TInputDirWizardPage;
DBPath: String;
procedure InitializeWizard;
begin
SelectDBPage := CreateInputDirPage(wpSelectDir, 'Select file', 'Select file', 'Select file', False, '');
SelectDBPage.Add('');
SelectDBPage.Values[0] := ExpandConstant('{src}\DB.FDB');
DBPath := SelectDBPage.Values[0];
end;
function GetDBPath():String;
begin
Result := DBPath;
end;
My problem is to retrieve file path. At instruction 'Source: {code:GetDBPath}' i get an 'Unknown filename prefix {code:' error.
How can I refer to the selected file path in [File] section?
Thank you

You need to add the external flag to the [Files] entry. This means the source will be evaluated at run time and CAN include {code:...} constants.
You're also not getting the correct value in your GetDBPath() function. You're returning the value of DBPath that isn't updated after creating the page, instead of getting the latest value form the SelectDBPage.Values[0].

Related

Inno Setup to modify key values in app.config file while running setup.exe

I need to change the values of some keys in app.config file. I'm planning to use Inno Setup for this task.
I have found excellent tips of using XML parser and xpath selectors in this kind of tasks. However, I don't know what path to use to point to the key & value I want to change.
My app.config looks approximately like this:
<configuration>
<runtime>
</runtime>
<appSettings>
<add key="DefaultUrl" value="http://localhost/Some_application"/>
</appSettings>
</configuration>
So, I want to access the key "DefaultUrl" and change it's "value". How to point there?
$x("//configuration/appSettings[#key='DefaultUrl']")
doesn't seem to be correct since it returns nothing.
EDIT after Mirtheil's comment:
To change the key values I use this procedure:
procedure SaveAttributeValueToXML(const AFileName, APath, AAttribute,
AValue: string);
var
XMLNode: Variant;
XMLDocument: Variant;
begin
XMLDocument := CreateOleObject('Msxml2.DOMDocument.6.0');
try
XMLDocument.async := False;
XMLDocument.load(AFileName);
if (XMLDocument.parseError.errorCode <> 0) then
MsgBox('The XML file could not be parsed. ' +
XMLDocument.parseError.reason, mbError, MB_OK)
else
begin
XMLDocument.setProperty('SelectionLanguage', 'XPath');
XMLNode := XMLDocument.selectSingleNode(APath);
XMLNode.setAttribute(AAttribute, AValue);
XMLDocument.save(AFileName);
end;
except
MsgBox('An error occured!' + #13#10 + GetExceptionMessage,
mbError, MB_OK);
end;
end;
I call it
SaveAttributeValueToXML(Some_Application.exe.config', '//configuration/appSettings[#key=''DefaultUrl'']', 'value', 'https://Server_Name/Other_Application');
This call generates an exception on line
XMLNode.setAttribute(AAttribute, AValue);
Exception message: "Variant is null, cannot invoke"
EDIT 2:
I found the answer. Calling
SaveAttributeValueToXML(Some_Application.exe.config', '//configuration/appSettings/add[#key=''DefaultUrl'']', 'value', 'https://Server_Name/Other_Application');
changes the value of key "DefaultUrl".
I found the answer.
$x("//configuration/appSettings/add[#key='DefaultUrl']")
returns the node I want.

How can I concat a defined variable in oracle?

I'm new in Oracle db and I'm working on script. So I trying to run a lot of scripts with a relative
var path and I have subfolder.
Folder A:
Folder A.Child-1
Folder A.Child-2
RunAll.sql
Folder A.Child-1:
Script 1
Script 2
I know we can define path var like:
define path='C:\Folder A.Child-1';
#&pathScr\RunAll.sql;
If I put a complete path for Eg: Script 1, the script can be exec. But is there any way to do something like:
define Scriptpath= Concat(&path, 'Folder A.Child-1')
#&Scriptpath\Script 1.sql;
So that I only need to declare the path only once.
What I tried:
define Scriptpath= concat(&path, 'Folder A.Child-1')
#&Scriptpath\Script 1.sql;
define Scriptpath= &path || 'Folder A.Child-1'
#&Scriptpath\Script 1.sql;
Declare Scriptpath:= = &path || 'Folder A.Child-1';
Begin
End;
#&Scriptpath\Script 1.sql;
All those trial return errors something like
Can not open file concat(&path, 'Folder A.Child-1')
You don't need concat, just use the same way with simple variable substitution in shell scripting:
SQL> def path1='mypath'
SQL> def path2='&path1/xyz.sql'
SQL> prompt &path1
mypath
SQL> prompt &path2
mypath/xyz.sql

Debugging non working Pascal Check condition (DirExists) in Inno Setup

I trying to compile a little setup program for future users, I have understood how change some stuff.
But now I would like to create a shortcut ONLY if the directory exist. I tried to do something like that but nothing happened ... :
[Icons]
; Start menu icon
Name: "{group}\Myprogram"; Filename: "{app}\Myprogram.exe"
; Desktop icon
Name: "{userdesktop}\Myprogram.exe"; Filename: "{app}\Myprogram.exe"; \
Check: DirExists(ExpandConstant('C:\[path]\test'))
Your code is ok. It should do what you want. To help with the debugging, implement a user function that logs the test like:
[Icons]
Name: "{userdesktop}\P680.exe"; Filename: "{app}\P680.exe"; \
Check: DirExistsLogged('C:\Users\administrator\Documents\Test')
[Code]
function DirExistsLogged(Path: string): Boolean;
begin
Result := DirExists(Path);
Log(Format('DirExists [%s] => %d', [Path, Result]));
end;
Log example, when the folder exists:
2019-12-31 15:04:59.565 DirExists [C:\Users\administrator\Documents\Test] => 1
2019-12-31 15:04:59.565 -- Icon entry --
2019-12-31 15:04:59.565 Dest filename: C:\Users\martin\Desktop\My Program.exe.lnk
2019-12-31 15:04:59.566 Creating the icon.
2019-12-31 15:04:59.583 Successfully created the icon.
2019-12-31 15:04:59.594 Saving uninstall information.
Log example, when the folder does not exist:
2019-12-31 15:06:23.960 DirExists [C:\Users\administrator\Documents\Test] => 0
2019-12-31 15:06:23.960 Saving uninstall information.

send mail with existing file as attachments using oracle procedure

DECLARE
attachments shr_pkg_send_mail.array_attachments:=shr_pkg_send_mail.array_attachments();
b_input_file BFILE:= BFILENAME('mount_dir', 'test02.txt');
c_output_file CLOB;
BEGIN
--DBMS_OUTPUT.PUT_LINE(c_output_file);
dbms_lob.open(b_input_file, DBMS_LOB.LOB_READONLY);
-- DBMS_OUTPUT.PUT_LINE('1');
dbms_lob.createtemporary(lob_loc => c_output_file, cache => false);
--DBMS_OUTPUT.PUT_LINE('2');
dbms_lob.open(c_output_file, DBMS_LOB.LOB_READWRITE);
--DBMS_OUTPUT.PUT_LINE('3');
dbms_lob.loadfromfile(c_output_file, b_input_file, DBMS_LOB.LOBMAXSIZE);
--DBMS_OUTPUT.PUT_LINE('4');
dbms_lob.close(b_input_file);
--DBMS_OUTPUT.PUT_LINE('5');
attachments.extend(1);
attachments(1).attach_name := 'test02.txt';
attachments(1).data_type := 'text/plain';
attachments(1).attach_content := c_output_file; SHR_PKG_SEND_MAIL.SEND_MAIL('EthicsandComplianceITSupport_ORG#dl.mgd.novartis.com','mansi.kekre#novartis.com','test','test',attachments => attachments);
dbms_lob.close(c_output_file);
END ;
ERROR
ORA-22285: non-existent directory or file for FILEOPEN operation
ORA-06512: at "SYS.DBMS_LOB", line 1014
ORA-06512: at line 8
Get the directory path
select directory_path from all_directories where directory_name='MOUNT_DIR'
Check if this path exists on database server and oracle has read access to it.
Check if the file 'test02.txt' exits in this path and is accessible.
Give grants to this directory
GRANT READ, WRITE ON DIRECTORY MOUNT_DIR TO <some_user>;
And here is something interesting, how to see files in directory with select, but you should have access to the SYS user.

How to Translate texts contained in MsgBox in Inno Setup?

I have got a [code] section contained within my inno setup script which displays some information for the user during install. I would like to be able to translate these in the same language the user selected during install. They texts are currently in English and for example want to translate it in Russian, etc. I know I have to do something in the Language.isl file. Below is a example of such text.
if MsgBox('Previous program found. It is recommendeded to uninstall it and install a fresh program. Please note that your data will not be deleted during the uninstallation. Do you want to continue?', mbConfirmation, MB_YESNO) = IDYES then
begin etc
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
[CustomMessages]
CustomMessage=Undefined //just in case (should be equal to English)
english.CustomMessage=English Selected
german.CustomMessage=German Selected
polish.CustomMessage=Polish Selected
[Code]
function InitializeSetup: Boolean;
begin
Result := True;
MsgBox(ExpandConstant('{cm:CustomMessage}'), mbInformation, MB_OK);
end;

Resources