我的软件中有一些用户可修改的文件,如果被修改,我不想在重新安装期间覆盖。
我决定使用存档位来指示用户是否修改了目标文件。在全新安装期间,所有相关文件的所有存档位都将设置为OFF。
存档关闭:表示此文件未修改,因此可以替换为最新版本 存档打开:表示该文件是由用户修改的,即使有较新的版本,也不应被安装程序覆盖。
注意:众所周知,根据设计,编辑和保存文件会将存档位设置为“开”。
我什至认为在NSIS脚本中使用robocopy,但是据我所知,robocopy的排除参数与源文件有关,而与目标文件无关。我使用下面的代码:
robocopy c:\source c:\target /XA:A
能否请您提供实现此类功能的线索。
答案 0 :(得分:0)
我认为无法通过File /r
来做到这一点。
当您手动提取每个文件时,您可以执行以下操作:
!include LogicLib.nsh
!define /IfNDef FILE_ATTRIBUTE_ARCHIVE 0x20
!define /IfNDef INVALID_FILE_ATTRIBUTES 0xffffffff
!define File_NoArchiveOverwrite "!insertmacro File_NoArchiveOverwrite "
!macro File_NoArchiveOverwrite sourcefile destinationfile
Push $1
System::Call 'KERNEL32::GetFileAttributes(ts)i.r1' "${destinationfile}"
${IfThen} $1 = ${INVALID_FILE_ATTRIBUTES} ${|} StrCpy $1 0 ${|} ; File does not exist? Make sure "it" has no attributes.
IntOp $1 $1 & ${FILE_ATTRIBUTE_ARCHIVE}
${If} $1 = 0 ; Archive not set?
SetOverwrite on
File "/oname=${destinationfile}" "${sourcefile}"
SetOverwrite lastused
${EndIf}
Pop $1
!macroend
Section "Example preparation"
InitPluginsDir
StrCpy $InstDir $PluginsDir ; Just a hack for this example
; Prepare some test files for this example:
File "/oname=$InstDir\test1.ini" "${__FILE__}"
SetFileAttributes "$InstDir\test1.ini" ARCHIVE
File "/oname=$InstDir\test2.ini" "${__FILE__}"
SetFileAttributes "$InstDir\test2.ini" NORMAL
SectionEnd
Section "Real code"
SetOutPath $InstDir
#File /r /x "*.ini" c:\myfiles\*.* ; Exclude .ini files because we handle them manually
${File_NoArchiveOverwrite} "${__FILE__}" "$InstDir\test1.ini" ; Not extracted because the dummy test1.ini file has ARCHIVE set
${File_NoArchiveOverwrite} "${__FILE__}" "$InstDir\test2.ini" ; This will overwrite the test2.ini dummy file.
${File_NoArchiveOverwrite} "${__FILE__}" "$InstDir\test3.ini" ; This file does not exist so we will extract a new file
SectionEnd
如果文件太多,无法手动创建${File_NoArchiveOverwrite}
调用,则可以使用!system
来调用批处理文件(或任何其他脚本或应用程序),该批处理文件会与{ {1}}个呼叫,然后您可以${File_NoArchiveOverwrite}
这个文件:
!include
这假设Section
SetOutPath $InstDir
!tempfile FILELIST
!system 'generatefilecommands.cmd "${FILELIST}"'
!include "${FILELIST}"
!delfile "${FILELIST}"
!undef FILELIST
SectionEnd
是您编写的文件,并且可能看起来像这样:
generatefilecommands.cmd