Archive: Copying a subset of files


Copying a subset of files
I've seen some posts that touch on this topic, but I haven't grocked exactly how to do it. Say I have a bunch of lang-specific files in my setup (added via File "blah blah").

At runtime I want to detect I'm on a Spanish system and only copy Somefile.spa vs Somefile.jpn. How can I do that? I've seen reference to CopyFiles using $Exedir, but haven't managed to make it work.

Is the general approach that you have to explode everything and *then* selectively delete vs selectively copy from the compressed file? I've looked around in the samples and haven't seen it (or don't know that I've seen it! ):)

I'm from the MSI world where we'd simply put a condition on a feature/component. Does NSI have the same concept/functionality or does it always all files?

Code snipped would rock if its anything other than CopyFiles/Delete.

Cheers!


You could prompt users to select their desired lang. Take a look here for a sample related script. Anyway you may examine the target system for local settings, windows version, user privileges, required runtimes etc, and set sections on/off. You have the option to pack your files within the installer or store them unpacked. Also you may download files at runtime execute them and continue your installation.


Thanks for the hints! The direction I'm trying to go now is to have a section for each lang file ala:

Section /o "Korean" kr
File "Foo\kr\Foo.exe"
SectionEnd

Section /o "English" en
File "Foo\en\Foo.exe"
SectionEnd

etc

My main section will then turn on the section that matches the lang I detect as the system lang, or what they select. I try to do that via:

SectionSetFlags $(LANG) ${SF_SELECTED}

where LANG is en, kr, jp, etc

This never appears to work. I always get a Copy Failed in the details pane.

I've tried calling this SectionSetFlags from within my main section and via calling a function from the main section. I've tried hard coding values vs using these vars.

I've put the lang section defs before and after the main section trying to catch any scope/defn issues. I'm not sure if there is any specific info I can gather from IfErrors other than there was an error vs getting detailed info (aka GetLastError()).

I saw some posts suggesting using macros in LogicLib, but if that is included it chokes on LangString definitions saying it was expecting 3 vs 4 params.

I'll keep playing with it and read more posts.

It seems similar in logic to posts I've seen so maybe I'm doing something illegal by calling it within a section vs a function, or some sort of order issue, etc.

Any ideas what might be up?


!include LogicLib.nsh
;
;
;
;
${if} $LANGUAGE == "English"
SectionSetFlags ${en} ${SF_SELECTED}
${else}
SectionSetFlags ${kr} ${SF_SELECTED}
${endif}


Hmm, I've tried calling SectionSetFlags ${en} ${SF_SELECTED} explicitly to test and still get the copy failed error. i.e.

Function SetLanguageSection
SectionSetFlags ${en} ${SF_SELECTED}
FunctionEnd

which is called from my main section. Does it matter if I call SectionSetFlags from a function vs a section? Neither appear to work for me, so that maybe a moot point!

Including LogicLib.nsh gives me LangString errors:

LangString expects 3 parameters, got 4.
Usage: LangString [un.]name lang_id string

They compile fine w/o that header, so not sure what is up there. I've tweaked the order of the includes. Same errors if LogicLib is there

In theory if calling SectionSetFlags directly fails I've got a bigger problem than the LogicLib issue. :(


outfile test.exe
licensedata '${NSISDIR}\license.txt'
ShowInstDetails show

LoadLanguageFile "${NSISDIR}\Contrib\Language files\English.nlf"
LoadLanguageFile "${NSISDIR}\Contrib\Language files\Greek.nlf"
LoadLanguageFile "${NSISDIR}\Contrib\Language files\French.nlf"

Insttype english
Insttype french
Insttype greek

page license
page components
page instfiles

section /o "english" sec1
sectionin 1

sectionend

section /o "french" sec2
sectionin 2

sectionend

section /o "greek" sec3
sectionin 3

sectionend

function .onInit
Push ""
Push ${LANG_ENGLISH}
Push English
Push ${LANG_FRENCH}
Push French
Push ${LANG_GREEK}
Push Greek
Push A
LangDLL::LangDialog "Installer Language" "Please select the language of the installer."
Pop $LANGUAGE
StrCmp $LANGUAGE "cancel" 0 +2
Abort

StrCmp $LANGUAGE '1033' 0 +2
SectionSetFlags ${sec1} 1

StrCmp $LANGUAGE '1036' 0 +2
SectionSetFlags ${sec2} 1

StrCmp $LANGUAGE '1032' 0 +2
SectionSetFlags ${sec3} 1
functionend

Thanks! I've got it now. I think I was getting tripped up by trying to be clever (Read:lazy) and having a single line:

SectionSetFlags ${LANGUAGE} 1

where my section names mapped to the same string (in your example) as the LANGID numbers. For some reason that never worked out correctly.

So something like:

section /o "english" 1033
sectionin 1
sectionend

...

Pop $LANGUAGE
...

SectionSetFlags ${LANGUAGE} 1

Maybe that can work and I've just got the syntax horked. I tried a few variations, but never hit it.

If I do the long form where I StrCmp against all X versions like you did and set them explicitly it works.

If you know why my previous all-in-one attempt fails that would be nice to know, but I'm good now and that is the important thing!

Thanks again for the help!


The syntax for section is:
Section section_name section_id
The syntax to set flags is:
SectionSetFlags ${section_id} 'flag'
So, what is supposed to do the SectionSetFlags ${LANGUAGE} 1
Is there any section with id LANGUAGE?


My attempt is to create a variable that contains the section name (en, kr) and have the SectionSetFlags call use that var so I can have a single call.

I must have had something else wrong earlier as now this appears to work. So something like (in pseudo code for brevity):

if English
StrCpy $(lang) "en"

if German
StrCpy $(lang) "de"

...

SectionSetFlags ${$(lang)} 1


Then create a macro that you'll be able to use on other similar installations in the future.