Archive: Customizing File command?


Customizing File command?
  Hi all,
I have some quite complicated requirements for using the File command, in order to overwrite program files, but not overwrite configuration etc. Unfortunately I don't even know which files are contained, but I know, that such configuration files end on e.g. .cfg Therefore I need to use /r instead of specifying each file separately.

Overwriting the program files is quite easy:
File /nonfatal /r /x *.cfg patch\partA\*.*

But for the *.cfg files I'd like to check whether they already exist, differ and take according actions like putting a file aside the existing one with ".new" appended to the name. And a summary file would be fine, so when running silently the user has a chance to know, which files need to be checked.

My first idea would be to unpack them to another location and implement my own script for diffing etc. Does that sound reasonable or are there macros available already for things like that. Or maybe can I implement a "custom" SetOverwrite mode?

Thx
siggel

PS: I have no influence on the incoming files, so I have no chance to do more sophisticated patching. Just in case you wonder...


The File command itself can't really be extended/customized for this purpose.
You're on the right track with extracting to a separate location, then enumerating the files extract, and using CopyFiles conditionally, as that is what gives you access to details about the source files, and the destination files (if existing).

Can't say there's an existing library. I started one a while back but realized that for a custom project it's pretty simple.. but for a generic solution you run into a whole host of problems stemming directly from the File command's complexity.
I.e. if you create a macro to wrap the File command, you'll either need separate macros for File /x, File /r, File /r /x, etc. or have a single Macro but with optional flags for everything; which would often go un-used.. meaning that a user's script might look like `${File} SomeFile.ext "" "" "" "" "" ""`

The way I started to solve that was using context defines.. e.g.

!define file.recursive
!define file.exclude *.svn
${File} "somefolder\*.*"
Where the defines would cause the actual File command being used to be `File /r /x *.svn "somefolder\*.*"`
But I'm not really working too actively on it.

Ideally the File command would trigger callbacks with some filled variables.. one before writing a file (so that you can Abort it if you decide not to write out the file), and one after writing it (so that you can perform logging or whatever, for use with /r mostly).

The other option that is generally used is to generate a file using another utility (or even another NSIS installer) that has single commands for each individual file - essentially replacing /r in a way - for inclusion in your main installer. You could use that to generate a more complex variant (wrapping the config files with a ${Unless} ${FileExists}) as well. Never been fond of that route, myself, though :)