2015-07-10 6 views

Antwort

5

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.

4

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 
+0

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

1

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.