Ich lese, dass "Strings länger als $ {NSIS_MAX_STRLEN} (1024) wird abgeschnitten/beschädigt."Update% PATH% Umgebungsvariable mit NSIS
Wie kann ich sicher Update % PATH% Umgebungsvariable?
Ich lese, dass "Strings länger als $ {NSIS_MAX_STRLEN} (1024) wird abgeschnitten/beschädigt."Update% PATH% Umgebungsvariable mit NSIS
Wie kann ich sicher Update % PATH% Umgebungsvariable?
Sie können ein alternatives NSIS-Build aus dem special builds page wie dem large strings build verwenden, das NSIS_MAX_STRLEN=8192
definiert und Sie daran hindern sollte, den Hostpfad zu unterbrechen. In der Praxis scheint auf einem Desktop-Rechner 1024 Byte genug zu sein, aber auf einem Entwicklungs-Host mit vielen installierten Werkzeugen (wie meiner) kann der Pfad nach der Manipulation unterbrochen sein, während die 8192 Byte langen Strings meine Maschine nie gestört haben .
Um ganz sicher zu sein, können Sie eine Überprüfung der Pfadlänge vor der Bearbeitung hinzufügen und das Installationsprogramm mit einer Meldung abbrechen, falls der Pfad nahe der NSIS_MAX_STRLEN
-Konstante liegt, bevor Sie versuchen, ihn zu manipulieren.
Die wirkliche Lösung ist ein eigenes Plugin oder rufen Sie den Windows-API direkt mit der System-Plugin zu schreiben, so dass Sie die NSIS Pufferlängenbegrenzung vermeiden:
!include LogicLib.nsh
!include WinCore.nsh
!ifndef NSIS_CHAR_SIZE
!define NSIS_CHAR_SIZE 1
!endif
Function RegAppendString
System::Store S
Pop $R0 ; append
Pop $R1 ; separator
Pop $R2 ; reg value
Pop $R3 ; reg path
Pop $R4 ; reg hkey
System::Call 'ADVAPI32::RegCreateKey(i$R4,tR3,*i.r1)i.r0'
${If} $0 = 0
System::Call 'ADVAPI32::RegQueryValueEx(ir1,tR2,i0,*i.r2,i0,*i0r3)i.r0'
${If} $0 <> 0
StrCpy $2 ${REG_SZ}
StrCpy $3 0
${EndIf}
StrLen $4 $R0
StrLen $5 $R1
IntOp $4 $4 + $5
IntOp $4 $4 + 1 ; For \0
!if ${NSIS_CHAR_SIZE} > 1
IntOp $4 $4 * ${NSIS_CHAR_SIZE}
!endif
IntOp $4 $4 + $3
System::Alloc $4
System::Call 'ADVAPI32::RegQueryValueEx(ir1,tR2,i0,i0,isr9,*ir4r4)i.r0'
${If} $0 = 0
${OrIf} $0 = ${ERROR_FILE_NOT_FOUND}
System::Call 'KERNEL32::lstrlen(t)(ir9)i.r0'
${If} $0 <> 0
System::Call 'KERNEL32::lstrcat(t)(ir9,tR1)'
${EndIf}
System::Call 'KERNEL32::lstrcat(t)(ir9,tR0)'
System::Call 'KERNEL32::lstrlen(t)(ir9)i.r0'
IntOp $0 $0 + 1
!if ${NSIS_CHAR_SIZE} > 1
IntOp $0 $0 * ${NSIS_CHAR_SIZE}
!endif
System::Call 'ADVAPI32::RegSetValueEx(ir1,tR2,i0,ir2,ir9,ir0)i.r0'
${EndIf}
System::Free $9
System::Call 'ADVAPI32::RegCloseKey(ir1)'
${EndIf}
Push $0
System::Store L
FunctionEnd
Section
Push ${HKEY_CURRENT_USER}
Push "Environment"
Push "Path"
Push ";"
Push "c:\whatever"
Call RegAppendString
Pop $0
DetailPrint RegAppendString:Error=$0
SectionEnd
Ich habe, das NSIS 3.0 Beispiel schrieb zu handhaben Fälle länger als das Limit und ohne etwas installieren zu müssen. Beantwortet die Frage hier: Set environment variables with NSIS in Window 7
Ich ziehe Windows-Kommando Prozessor (cmd.exe
) über den NSIS nsExec::Exec
Befehl, mit dem Sie auf die PATH
leicht wie so anhängen können:
; Check if the path entry already exists and write result to $0
nsExec::Exec 'echo %PATH% | find "c:\some\new\dir"'
Pop $0 ; gets result code
${If} $0 = 0
nsExec::Exec 'set PATH=%PATH%;c:\some\new\dir'
${EndIf}
Mit dieser Methode CMD.EXE
erweitert Die interne Variable PATH
ist sicher vor NSIS-String-Längenbeschränkungen. Alternativ die Reihenfolge der %PATH%
token einfügen ändern, wenn Sie Ihr Programm wollen erste abgeholt werden, vor allem und alles andere, was mit dem gleichen Namen auf dem System installiert werden:
nsExec::Exec 'set PATH=c:\some\new\dir;%PATH%'
Beachten Sie auch, dass es ist wichtig, nicht zu enthalten, doppelte Anführungszeichen beim Erstellen der neuen PATH
. Der Befehlsprozessor erwartet niemals doppelte Anführungszeichen in der PATH-Zeichenfolge und verhält sich möglicherweise auf unerwartete Weise, wenn Sie eine hinzufügen. Er begrenzt Pfade nur durch Semikolon (;
).
nsExec::Exec
unterscheidet sich von ExecWait
, dass es intern ausgeführt wird, ohne zusätzliche sichtbare cmd Prompt Fenster auftauchen.
Ich habe nur kleinere Tests auf die Funktion RegAppendString, idealerweise würden Sie Null Beendigung erzwingen, überprüfen, ob es bereits das Trennzeichen am Ende hat und dies alles in einer Schleife durchführen, um Probleme mit der Zeichenfolge zwischen den Aufrufen von RegQueryValueEx zu ändern . – Anders