I'm trying to read a node value from an xml file and store it in a variable to put it back into another xml file. I'm doing this inside an NSIS installer using NSIS XML plugin (By Wizou), the problem i'm facing is its not reading the node value, the code i'm using is below,
nsisXML::create
nsisXML::load '${CONFIG}' /* This is the XML file for reading the value*/
messagebox MB_OK "Value in var0 is $0"
nsisXML::select '/hibernate-configuration/session-factory/property[#name="connection.connection_string"]'
messagebox MB_OK "Value in var1 is $1"
messagebox MB_OK "Value in var2 is $2"
After the initial load of the file(File exists in the referred path), i'm getting some value in $0 which means xml file is getting loaded, after which i'm trying to select the node from where it reads the value. But after the nsisxml::select statement the var's $1 and $2 has value 0 which suggests it can't find the node, but its there in the xml when you look at it, the XML file contents are below,
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">
NHibernate.Connection.DriverConnectionProvider
</property>
<property name="dialect">
NHibernate.Dialect.MsSql2005Dialect
</property>
<property name="connection.driver_class">
NHibernate.Driver.SqlClientDriver
</property>
<property name="connection.connection_string">
DB String
</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name="cache.provider_class">NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache</property>
</session-factory>
</hibernate-configuration>
Any idea where i could be going wrong with this? thanks in advance
The problem is that your XPath search string does not deal with the xmlns.
You can ignore the xmlns like this:
InitPluginsDir
FileOpen $0 "$pluginsdir\Test.xml" w
FileWrite $0 '<?xml version="1.0" encoding="utf-8" ?>$\r$\n'
FileWrite $0 '<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">$\r$\n'
FileWrite $0 '<session-factory>$\r$\n'
FileWrite $0 '<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>$\r$\n'
FileWrite $0 '<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>$\r$\n'
FileWrite $0 '<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>$\r$\n'
FileWrite $0 '<property name="connection.connection_string">DB String</property>$\r$\n'
FileWrite $0 `<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>$\r$\n`
FileWrite $0 '<property name="cache.provider_class">NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache</property>$\r$\n'
FileWrite $0 '</session-factory>$\r$\n'
FileWrite $0 '</hibernate-configuration>$\r$\n'
FileClose $0
nsisXML::create
nsisXML::load "$pluginsdir\Test.xml"
DetailPrint doc=$0
nsisXML::select `/*[name()='hibernate-configuration']/*[name()='session-factory']/*[name()='property'][#name="connection.connection_string"]`
DetailPrint 1=$1,2=$2,3=$3
Related
I am trying read the directory from text file but it did't working!
the test.txt is a two lines file ,a line per directory.
anyone can help me?
; example1.nsi
;
; This script is perhaps one of the simplest NSIs you can make. All of the
; optional settings are left to their default settings. The installer simply
; prompts the user asking them where to install, and drops a copy of example1.nsi
; there.
;--------------------------------
; The name of the installer
Name "Example1"
; The file to write
OutFile "example1.exe"
; The default installation directory
InstallDir $DESKTOP
; Request application privileges for Windows Vista
RequestExecutionLevel admin
!include "LogicLib.nsh"
!include FileFunc.nsh
ShowInstDetails show
;--------------------------------
; Pages
;--------------------------------
Function .onInit
functionend
; The stuff to install
Section "" ;No components page, name is not important
FileOpen $0 "test.txt" r
;FileSeek $4 1000 ; we want to start reading at the 1000th byte
FileRead $0 $1 ; we read until the end of line (including carriage return and new line) and save it to $1
FileRead $0 $2
;FileRead $4 $2 10 ; read 10 characters from the next line
FileClose $0 ; and close the file
DetailPrint $1
DetailPrint $2
CopyFiles $1 "D:\Desktop\taobao"
; Set output path to the installation directory.
SetOutPath $INSTDIR
SectionEnd ; end the section
FileOpen $0 "test.txt" r is problematic for two reasons.
You are not using a full path.
I'm assuming this file does not already exist on the end-users machine. You probably need to extract it from the installer before you can read it.
Another problem is that FileRead includes the newline characters in the returned string and you must remove them if you don't need them. Newline characters are not valid in paths on Windows.
; Create simple text file for this example:
!delfile /nonfatal "myexample.txt"
!appendfile "myexample.txt" "Hello$\r$\n"
!appendfile "myexample.txt" "W o r l d$\r$\n"
!include "StrFunc.nsh"
${StrTrimNewLines} ; Tell StrFunc.nsh to define this function for us
Section
SetOutPath $InstDir
InitPluginsDir ; Make sure $PluginsDir exists (it is automatically deleted by the installer when it quits)
File "/oname=$PluginsDir\data.txt" "myexample.txt" ; Extract our myexample.txt file to $PluginsDir\data.txt
FileOpen $0 "$PluginsDir\data.txt" r
FileRead $0 $1
${StrTrimNewLines} $1 $1
FileRead $0 $2
${StrTrimNewLines} $2 $2
FileClose $0
DetailPrint "Line 1=$1"
DetailPrint "Line 2=$2"
SectionEnd
I'm trying to append 1 line of text into a file on the $APPDATA folder which is inside of a folder that's generated randomly, so I don't know it's full path like:
C:\Users\MyUser\AppData\Roaming\MyApp\RANDOM_CRAP\config.json
While RANDOM_CRAP looks like some random string for a folder, like G4F6Hh3L.
What are my options here? Do I need to use either Search For a File or Search for a File or Directory (Alternative) ? It's a given that the only subfolder of MyApp folder is the RANDOM_CRAP folder, that contains the file I want to edit.
If there's no other way to access this file without searching for it, I've tried doing so but couldn't get this to work. (I'm very new to NSIS)
This is what I've tried (With the alternative approach):
Push "config.json"
Push "$APPDATA"
Push $0
GetFunctionAddress $0 "myCallback"
Exch $0
Push "1" ; include subfolders because my desired file is in the random folder
Push "0" ; no need the . option
Call SearchFile
Than I've copied the SearchFile code from this post and put a callback:
Function myCallback
Exch 3
Pop $R4
MessageBox MB_OK "Callback executing!"
MessageBox MB_OK "File is at : $R4"
FunctionEnd
I know that SearchFile is running (I've put a MessageBox inside) but myCallback isn't seemed to be called.
Many thanks.
If you are looking for a known file and only one directory in the path is unknown then you can probably just do a basic FindFirst search:
Section
; Create "random" folders:
CreateDirectory "$temp\MyApp\foo"
System::Call kernel32::GetTickCount()i.r1 ; random enough
CreateDirectory "$temp\MyApp\bar$1"
FileOpen $0 "$temp\MyApp\bar$1\config.json" a
FileWrite $0 '{bogus:"data"}$\n'
FileClose $0
CreateDirectory "$temp\MyApp\baz"
!include LogicLib.nsh
; Do the actual search:
StrCpy $9 "$temp\MyApp" ; The folder we are going to search in
FindFirst $0 $1 "$temp\MyApp\*"
loop:
StrCmp $1 "" done
${If} ${FileExists} "$9\$1\config.json"
DetailPrint "Found: $9\$1\config.json"
${EndIf}
FindNext $0 $1
Goto loop
done:
FindClose $0
SectionEnd
In an NSIS installer script, I'm trying to check if a given httpd.conf file contains the following line :
Include "c:\xxx\yyy.conf"
If so, then my installer script would not append it to the file, otherwise, it would append it.
I've come through {LineFind} but not sure this really makes what i'm trying to achieve.
What could be the simplest way to do a kind of "grep" on a text file from an NSIS script ?
Thank you !
Here is a sample for searching for a given line into a file, using the LogicLib for ease of syntax. The search is stopped as soon as the line is found. This sample works on the sample script itself:
# find.nsi : sample for LineFind from TextFunc.nsh
!include "textfunc.nsh"
!include "logiclib.nsh"
OutFile "find.exe"
!define lookfor `Section` ;will find
;!define lookfor `Sectionn` ;will not find
Var found
Section
StrCpy $found 0
${LineFind} "find.nsi" "/NUL" "1:-1" "GrepFunc"
${if} $found = 1
MessageBox MB_OK "string found"
${else}
MessageBox MB_OK "string NOT found"
${endIf}
SectionEnd
Function GrepFunc
${TrimNewLines} '$R9' $R9
DetailPrint "test for line $R8 `$R9`"
${if} $R9 == "${lookfor}"
StrCpy $found 1 ;set flag
Push "StopLineFind" ;stop find
${else}
Push 0 ;ignore -> continue
${endIf}
FunctionEnd
I have created nsi file for my java project.I have created a Textbox and gave as default value.My problem is running the exe file it displays textbox with default value.If the user wants to modify the value in text box that should be Written in property file.I have tried following lines code
InstallOptions::dialog "$PLUGINSDIR\sample.ini"
ReadINIStr $0 "$PLUGINSDIR\sample.ini" "Field 1" State
${ConfigWrite} "$INSTDIR\resource\conf.properties" "AGENT.HOST" "=$0" $R0
But the modified values will be affected in property file.I dont know why this isnot reflected? can anyone help me?
!include LogicLib.nsh
!include TextFunc.nsh
Function pageConfig
InitPluginsDir
# For this example I generate the page directly with the precompiler, you probably want to use a real .ini file.
!tempfile SRCINI
!appendfile "${SRCINI}" "[Settings]$\nNumFields=1$\n"
!appendfile "${SRCINI}" "[Field 1]$\n"
!appendfile "${SRCINI}" "Type=Text$\n"
!appendfile "${SRCINI}" "Left=10$\nRight=100$\nTop=10$\nBottom=24"
File "/oname=$PluginsDir\cfgpage.ini" "${SRCINI}"
!delfile "${SRCINI}"
ClearErrors
${ConfigRead} "$INSTDIR\resource\conf.properties" "AGENT.HOST=" $0
${If} ${Errors}
StrCpy $0 "DefaultHost.com"
${EndIf}
WriteIniStr "$PluginsDir\cfgpage.ini" "Field 1" "State" $0
InstallOptions::dialog "$PluginsDir\cfgpage.ini"
Pop $0
FunctionEnd
Function pageLeaveConfig
ReadINIStr $0 "$PluginsDir\cfgpage.ini" "Field 1" State
${If} $0 == ""
MessageBox mb_iconstop "Please provide a host..."
Abort
${EndIf}
${ConfigWrite} "$INSTDIR\resource\conf.properties" "AGENT.HOST=" "$0" $1
FunctionEnd
Page custom pageConfig pageLeaveConfig
I am new to NSIS scripting installer. I need to create a TextBox with Multiline support, in Custom page. Need to read a text file and set the text content to TextBox. Please find my code block below:
StrCpy $3 ""
FileOpen $4 "C:\Users\Surya\Desktop\Installer\License.txt" r
loop:
FileRead $4 $1
StrCpy $3 "$3$1" ; append the line and copy it to another variable
IfErrors +1 loop
FileClose $4
${NSD_SetText} $ctrlTextBox "$3"
The above code able to read only 8119 characters only, but my file contains 30,000+ characters.
Please help me to read the large file and set the content to TextBox.
Thank You
You can fill a textbox with a little bit of text at the time (inside your loop) if you use EM_SETSEL (twice) to move the caret to the end and then use EM_REPLACESEL to append text.
If you can use a rich edit box instead then use some code I wrote a long time ago, you can find the forum thread here...
Edit:
As long as the textbox is empty when you begin you don't have to deal with the caret:
function custcreate
nsDialogs::Create 1018
Pop $0
nsDialogs::CreateControl ${__NSD_Text_CLASS} ${__NSD_Text_STYLE}|${ES_MULTILINE}|${WS_VSCROLL}|${ES_READONLY} ${__NSD_Text_EXSTYLE} 0 0 100% 50u ""
Pop $0
FileOpen $4 ${__FILE__}" r
loop:
FileRead $4 $1
SendMessage $0 ${EM_REPLACESEL} 0 "STR:$1"
IfErrors +1 loop
FileClose $4
nsDialogs::Show
functionend