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

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.

Related

How to serve file referenced from HTML file using WebBroker (TIdHTTPWebBrokerBridge) and TWebModule

I built tiny http server (Delphi 10.2) to return some calculations to client on-line.
I used page producer with TPageProducer.HTMLFile set to local file.
The test.html file has reference to css file on local disk like: <link rel="stylesheet" href="data/style.css"> in the head section. It works from Firefox styling my html.
To be able to serve this css file from local folder I handled WebModule.BeforeDispatch:
procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest;
Response: TWebResponse; var Handled: Boolean);
var
LocalPath: String;
begin
if Request.PathInfo.StartsWith('/data/') then
begin
LocalPath := DataPath + StringReplace(Request.PathInfo, '/', '\', [rfReplaceAll]);
if FileExists(LocalPath) then
begin
Response.ContentStream := TFileStream.Create(LocalPath, fmShareDenyWrite);
Assert(Response.ContentStream.Size > 0);
end;
Handled := True;
end;
end;
When I run my server and go to address: http://localhost/data/style.css
I obtain proper contents of style.css file in a browser window as a result.
Why is it not used as style for my HTML file even if it is correctly read in OnBeforeDispatch when using address like http://localhost/test.html?
It seems that one file (CSS) is referenced from other (HTML) and this makes things cluttered.

how the 'tmpdata' and 'Get_Parameter_List' works in OracleForm?

I am new in OracleForms and Plsql, i found this code in a proyect:
PROCEDURE grabar IS
...
Pl_id paramlist;
...
BEGIN
pl_id := Get_Parameter_List ('tmpdata');
IF NOT Id_Null(pl_id) THEN
Destroy_Parameter_List( pl_id );
END IF;
pl_id := Create_Parameter_List('tmpdata');
i want to konw that if 'tmpdata' does not exist i will get an error?
whit the line:
pl_id := Get_Parameter_List ('tmpdata');
am i inserting the data of 'tmpdata' in 'PL_id'
it is the 'tmpdata' a default variable of Oracleforms or something?
it is not OracleForms but it is a tool based in it so is so similar
I proved to change to:
pl_id := Get_Parameter_List ('tmpdata_HELLO');
enter code hereand the program passed to of this
the console show me this:
may 25, 2018 4:46:30 PM org.apache.tomcat.util.http.Parameters processParameters
INFORMACIÓN: Character decoding failed. Parameter [value] with value [%null] has been ignored. Note that the name and value quoted here may be corrupted due to the failed decoding. Use debug level logging to see the original, non-corrupted values.
Note: further occurrences of Parameter errors will be logged at DEBUG level.
In this example, "tmpdata" is the name of a parameter list that may or may not exist. The "ID_NULL" is checking for the existence of the parameter list by checking of the ID returned has a value or not. If it has a value (ie, ID_NULL returns FALSE), then the parameter list is destroyed so that the "Create_Parameter_List" command will not get an error.
"Get_Parameter_List" will not throw an error if there is no parameter list by the given name ("tmpdata", in this case); it just returns null.

dbms_xmldom - How to get the <?xml tag

I am trying to get the line <?xml ....?> at the start of the XML document using the PL/SQL Package dbms_xmldom. Here is the code so far
declare
l_dom dbms_xmldom.DOMDocument;
l_clob clob;
l_node dbms_xmldom.DOMNode;
begin
l_dom := dbms_xmldom.newDomDocument;
l_node := dbms_xmldom.makeNode(l_dom);
l_node := dbms_xmldom.appendChild(l_node,
dbms_xmldom.makeNode(
dbms_xmldom.createElement(l_dom, 'root')
)
);
dbms_lob.createtemporary(l_clob, true);
dbms_xmldom.writeToClob(l_dom, l_clob);
dbms_output.put_line(l_clob);
end;
The output is:
<root/>
Expect:
<?xml version="1.0" encoding="UTF-8"?>
<root/>
Any pointers on how to do this would get great.
Just for the record - here is what you need to add
dbms_xmldom.setVersion(l_dom, '1.0" encoding="UTF-8');
after creating the document
The prolog is usually added automatically by XML serialization, so you shouldn't need to add it yourself, but if you want to you can with XMLRoot.
Your method for generating XML is quite inefficient. You should be looking at XMLElement, XMLForest, XMLAgg etc.
Here's a simple root and child example, with prolog in one line of code.
select XMLRoot(XMLElement("root", XMLElement("child", 12)), version '1.0') from dual
<?xml version="1.0"?>
<root>
<child>12</child>
</root>

Executing SQL Script using OSQL do not return resultcode

I am executing some sql queries using OSQL through inno setup. I am using following code to run OSQL. This is just for example purpose
SQLQuery:= '"EXEC sp_addserver ''PCNAME'';"';
Param:= '-S(local) -Usa -Psa -Q ' + SQLQuery;
Exec('osql.exe', Param, '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
This works fine. The problem is ResultCode value is always 0. Even if the query does not get executed. For example if I try same query like below where I pass in an invalid stored procedure name the ResultCode is still 0.
SQLQuery:= '"EXEC sp_invalidname ''PCNAME'';"';
Param:= '-S(local) -Usa -Psa -Q ' + SQLQuery;
Exec('osql.exe', Param, '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
Why don't this return me a proper code. If I run the second query in management studio I get an error like this
Msg 2812, Level 16, State 62, Line 1
Could not find stored procedure 'sp_invalidname'
Here return code is 2812. Why dont I get this when I run it through inno. What do I need to do to get this error code in inno?
Thanks to TLama, I updated my code as below and its working now. I had to add -b command line parameter and now it returns 1 if the command fails.
-b
Specifies that osql exits and returns a DOS ERRORLEVEL value when an error occurs. The value returned to the DOS ERRORLEVEL variable is 1 when the SQL Server error message has a severity of 11 or greater; otherwise, the value returned is 0. Microsoft MS-DOS batch files can test the value of DOS ERRORLEVEL and handle the error appropriately.
I updated my code as below.
Param:= '-S(local) -Usa -Psa -b -Q ' + SQLQuery;
Its explained in the documentation.

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

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

Resources