Greifen Sie über Powershell-Skript auf den neuen Pfad zu

585
Eos Pengwern

Ich schreibe ein Powershell-Skript, um eine Build-Umgebung zu konfigurieren und dann den Build auszuführen. Dazu müssen Sie den Systempfad so einstellen, dass er das Compiler- und Build-System (in diesem Fall qmake und mingw32-make) enthält, und dann mit dem Build fortfahren.

Ich habe die Dinge so eingerichtet, dass sich die Funktion zum Ändern des Systempfads, die weitgehend auf dieser Referenz basiert, in einer separaten Datei wie dieser befindet:

Function AddTo-UserPath { Param ( [Parameter(mandatory=$true)] [System.IO.DirectoryInfo[]]$PathsToAdd )  $MachinePath = [System.Environment]::GetEnvironmentVariable('PATH','Machine') $UserPath = [System.Environment]::GetEnvironmentVariable('PATH','User') $VerifiedPathsToAdd = $Null $MachinePathArray = $MachinePath -Split ‘;’ -replace ‘\\+$' $UserPathArray = $UserPath -Split ‘;’ -replace ‘\\+$' Foreach ($PathToAdd in ($PathsToAdd | % { $_.FullName.TrimEnd(‘\’) } ) ) { if($MachinePathArray -contains $PathToAdd) { Write-Verbose “$PathToAdd already exists in Machine Path” } elseif($UserPathArray -contains $PathToAdd) { Write-Verbose “$PathToAdd already exists in User Path” } else { $VerifiedPathsToAdd += ";$PathToAdd" } }  if($VerifiedPathsToAdd -ne $null) { [Environment]::SetEnvironmentVariable('PATH', $UserPath + $VerifiedPathsToAdd, 'User') } } 

... damit ich in meine Hauptskriptdatei schreiben kann:

# Load the module containing the AddTo-UserPath function Import-Module $PSScriptRoot\..\ps1utils\myfunctions.ps1  # Add the required directories to the system path AddTo-UserPath C:\Qt\Tools\mingw530_32\bin, C:\Qt\5.9.7\mingw53_32\bin  # Start the build qmake qwt.pro mingw32-make -j mingw32-make -j install 

Wenn ich mein Skript von der Powershell-ISE aus ausführe, kann ich einen Haltepunkt in die Zeile "qmake" setzen und in der Windows-Benutzeroberfläche überprüfen, ob mein Pfad nach Bedarf geändert wurde. Ich kann sogar ein separates cmd-Fenster öffnen und qmake und mingw32-make recht glücklich ausführen. Mein Skript gibt mir jedoch die Fehler:

qmake : The term 'qmake' is not recognized as the name of a cmdlet, function, script file, or operable program. mingw32-make : The term 'mingw32-make' is not recognized as the name of a cmdlet, function, script file, or operable program.  

... und wenn ich den Wert von $ env: Path überprüfe, dann spiegelt es sicher nicht die gerade vorgenommenen Änderungen wider.

In gewisser Weise ist das nicht überraschend; Ich habe oft gelesen, dass wenn Sie den Systempfad aus einem Powershell-Fenster heraus ändern, Sie das Fenster schließen und erneut öffnen müssen, damit die Änderung wirksam wird. Das Problem ist, dass ich nicht aus meinem Skript herausfinden kann, wie man es umgehen kann. Der einzige Punkt dabei ist, meinen Build-Prozess zu automatisieren. Daher ist es kaum angebracht, dass ich ein Powershell-Fenster manuell schließen und öffnen muss eine andere, bevor mein Skript fortfahren kann. Es muss einen besseren Weg geben.

Mir fiel auf, dass ich vielleicht einen neuen Prozess erzeugen musste, also versuchte ich, meine Build-Befehle in eine separate Skriptdatei zu schreiben und zu schreiben:

AddTo-UserPath C:\Qt\Tools\mingw530_32\bin, C:\Qt\5.9.7\mingw53_32\bin powershell -file TheRestOfMyBuildProcess.ps1 

... aber das hat auch nicht funktioniert.

Jetzt habe ich keine Ideen mehr, ich konnte keine Lösung online finden, und ich würde gerne wissen, wie man dies richtig macht.

1

1 Antwort auf die Frage

1
harrymc

Das Ändern des PFADs in PowerShell ist für die aktuelle Sitzung isoliert und nur temporär. Dies ist das, was Sie sehen.

Sie können die Umgebungsvariable PATH dauerhaft ändern, indem Sie sie direkt in der Registrierung ändern. Alle Variablen werden unter dem Registrierungsschlüssel gespeichert HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment.

Ein PowerShell-Skript zum Hinzufügen zu PATH sieht folgendermaßen aus:

$oldPath=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path  $newPath=$oldPath+’;C:NewFolderToAddToTheList’  Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' -Name PATH –Value $newPath 

Sie müssen PowerShell neu starten, um die Änderung zu sehen. Ab jetzt verwenden jedoch alle Anwendungen den aktualisierten PATH.

Dies wurde im Artikel "Hey, Scripting Guy! Blog" gefunden. Verwenden Sie PowerShell, um Ihren Umgebungspfad zu ändern . Dort finden Sie weitere Informationen und Ideen.

Ein weiterer nützlicher Beitrag ist Reload the path in powershell, wo die folgende Syntax vorgeschlagen wurde:

$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") 
Danke für Ihre Antwort, aber ich fürchte, das hilft mir nicht. Was ich sehe, hat nichts damit zu tun, dass die Pfadänderung nur vorübergehend ist. Da ich dies mit dem Befehl .Net SetEnvironmentVariable mache, ist es tatsächlich permanent. Ich habe das sorgfältig getestet. Das Problem ist einfach, dass Powershell den aktualisierten Pfad nicht sieht. Was ich brauche, ist eine Möglichkeit, Powershell dazu zu zwingen, es zu sehen, selbst wenn Powershell programmgesteuert neu gestartet und mein Skript fortgesetzt werden muss. Da es sich bei Powershell um Automatisierung handeln soll, ist es schwer zu glauben, dass es keine Möglichkeit gibt, einen Build wie diesen zu automatisieren. Eos Pengwern vor 5 Jahren 0
Sie müssen Powershell neu starten, um PATH neu zu erstellen, jedoch nicht als untergeordnetes Element des aktuellen Skripts, da das untergeordnete Element die Umgebung des übergeordneten Objekts erbt. Ich habe eine mögliche Lösung hinzugefügt, um den PATH nach einer dauerhaften Änderung in der aktuellen Sitzung neu zu laden. harrymc vor 5 Jahren 0
Das sieht vielversprechender aus, aber ich fürchte, ich werde es 24 Stunden lang nicht ausprobieren können. Ich lasse Sie wissen, ob es den Trick tut, und akzeptiere Ihre Antwort, wenn dies der Fall ist. Eos Pengwern vor 5 Jahren 0
Keine Eile und viel Glück. harrymc vor 5 Jahren 0
Ja, das ist es genagelt. Ich akzeptiere jetzt deine Antwort. Eos Pengwern vor 5 Jahren 0