Legen Sie eine persistente Umgebungsvariable aus cmd.exe fest

123

Ich muss Umgebungsvariablen auf verschiedenen Windows-Computern festlegen, möchte aber nicht die Mühe machen, sie manuell zu ändern, indem ich auf den Eigenschaftenbildschirm von "Arbeitsplatz" gehe.

Ich möchte es über die Befehlszeile mit einer Batch-Datei tun. Soweit ich weiß, ändert die Verwendung von set nur die Variable für die Prozesse, die ich im Befehlsfenster aufrufe.

Ich möchte es definitiv festlegen. Wenn später ein neuer Prozess ausgeführt wird, werden die von mir festgelegten neuen Einstellungen verwendet. Gibt es eine Möglichkeit, dies über die Befehlszeile zu tun?

Arthur
quelle
Was bringt es, sie über die Befehlszeile festzulegen, wenn sie dauerhaft sind? Sie müssen es nicht noch einmal tun.
D-Live
12
Ja, aber ich muss es auf mehreren Computern tun, sodass ich einige Zeit sparen kann, wenn ich das Skript ausführe.
Arthur
2
Ok, in diesem Fall können Sie Ihre Umgebung auf einem Computer einstellen und die unten beschriebenen Einträge exportieren und eine .reg-Datei haben, wenn SETX Ihnen nicht zur Verfügung steht.
D-Live
Das habe ich getan. Vielen Dank.
Arthur
1
RE: 'Was bringt es, sie über die Befehlszeile festzulegen ...' Wo ich arbeite, müssen ständig mehrere persistente Umgebungsvariablen auf unterschiedliche Werte eingestellt werden, um verschiedene Versionen der Software zu testen / zu entwickeln. Lizenzierung bedeutet, dass dies nicht auf andere Weise möglich ist (z. B. durch Ausführen einer VM). Daher besteht unser einziger Ausweg darin, SETX in einem Batch-Skript zu verwenden. Die Verwendung von .reg ist weniger gut, da es schwieriger ist, genau zu dokumentieren / zu sehen, was los ist
Tony Eastwood

Antworten:

189

Verwenden Sie den Befehl SETX (beachten Sie das Suffix 'x'), um Variablen festzulegen , die nach dem Schließen des cmd-Fensters bestehen bleiben.

So legen Sie beispielsweise eine env var "foo" mit dem Wert "bar" fest:

setx foo bar

Es lohnt sich jedoch, die 'Notizen' zu lesen, die angezeigt werden, wenn Sie die Verwendung ( setx /?) drucken , insbesondere:

2) Auf einem lokalen System sind Variablen, die mit diesem Tool erstellt oder geändert wurden, in zukünftigen Befehlsfenstern verfügbar, jedoch nicht im aktuellen Befehlsfenster CMD.exe.

3) Auf einem Remote-System sind Variablen, die mit diesem Tool erstellt oder geändert wurden, bei der nächsten Anmeldesitzung verfügbar.

In PowerShell den Befehl [Environment] :: SetEnvironmentVariable .

Vik David
quelle
Es scheint, dass SETX nur unter Windows XP SP2 verfügbar ist
Arthur
2
Es hat unter Windows 7 für mich funktioniert. Welche Windows-Version verwenden Sie?
Vik David
@jules: Sie können es dann aus dem Resource Kit herunterladen.
Joey
45
Seien Sie vorsichtig mit SETX, es schneidet Ihre variable Länge auf 1024 Zeichen ab ... sehr gefährlich, wenn Sie% path% manipulieren.
Etienne Desgagné
2
mit Power Shell können Sie einfach [Environment]::SetEnvironmentVariable('PATH', "Whatever you need it to be", "Machine")finden msdn.microsoft.com/en-us/library/96xafkes(v=vs.110).aspx
Gradient
21

In der MSDN-Dokumentation für Umgebungsvariablen erfahren Sie, was zu tun ist:

Um Systemumgebungsvariablen programmgesteuert hinzuzufügen oder zu ändern, fügen Sie sie dem Registrierungsschlüssel HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment hinzu und senden Sie dann eine WM_SETTINGCHANGE- Nachricht, wobei lParam auf die Zeichenfolge "Environment" gesetzt ist. Auf diese Weise können Anwendungen wie die Shell Ihre Updates abrufen.

Dazu benötigen Sie natürlich Administratorrechte. Ich kenne keine Möglichkeit, eine Windows-Nachricht aus dem Windows-Stapel zu senden, daher müssen Sie dazu ein kleines Programm schreiben.

David Heffernan
quelle
1
In Anbetracht Ihrer Lösung habe ich eine Registrierungsdatei (.reg) erstellt, die die Umgebungsvariablen enthält, die ich hinzufügen / ändern möchte. Ich werde diese Datei dann auf allen Ziel-PCs ausführen. Ich muss keine Windows-Nachricht senden, da ich nur die betroffene Anwendung neu starten werde. Vielen Dank.
Arthur
1
Ich füge
bin
1
@ David, warum also nicht setxunten?
Pacerier
Ich denke, diese Registrierung hat den Vorteil, dass sie nicht abschneidet und keine Powershell ist
eri0o
2
' SetVar.vbs
Sub sety(wsh, action, typey, vary, value)
  Dim wu
  Set wu = wsh.Environment(typey)
  wui = wu.Item(vary)
  Select Case action
    Case "ls"
      WScript.Echo wui
    Case "del"
      On Error Resume Next
      wu.remove(vary)
      On Error Goto 0
    Case "set"
      wu.Item(vary) = value
    Case "add"
      If wui = "" Then
        wu.Item(vary) = value
      ElseIf InStr(UCase(";" & wui & ";"), UCase(";" & value & ";")) = 0 Then
        wu.Item(vary) = value & ";" & wui
      End If
    Case Else
      WScript.Echo "Bad action"
  End Select
End Sub

Dim wsh, args
Set wsh = WScript.CreateObject("WScript.Shell")
Set args = WScript.Arguments
Select Case WScript.Arguments.Length
  Case 3
    value = ""
  Case 4
    value = args(3)
  Case Else
    WScript.Echo "Arguments - 0: ls,del,set,add; 1: user,system, 2: variable; 3: value"
    value = "```"
End Select
If Not value = "```" Then
  ' 0: ls,del,set,add; 1: user,system, 2: variable; 3: value
  sety wsh, args(0), args(1), UCase(args(2)), value
End If
Justin Peal
quelle
21
Sie sollten in Betracht ziehen, einen Kontext oder eine Erklärung zu Ihrem Code hinzuzufügen.
Adamdunson
1
Leistungsstarker Code +1. Funktioniert unter XP ohne setx(und ohne Installationsmöglichkeit). Einfache Verwendung (in meinem Fall):wsh.Environment("user").Item("myVar") = "my value"
Marek
2
Da sich niemand die Mühe gemacht hat, unter XP (kein Resource Kit oder Setx erforderlich) für alle (anderen) DOS-Fenster {set foo = bar} auszuführen: 1. Speichern Sie den obigen Code als SetVar.vbs 2. setvar. vbs set system foo "bar" Hinweis: Das aktuelle DOS-Fenster erhält davon kein FOO. Setzen Sie foo = bar, um dies zu erreichen
MicrosoftShouldBeKickedInNuts
2
Beachten Sie auch, dass dies den Neustart überlebt (wenn Sie den Systemparameter verwenden)
MicrosoftShouldBeKickedInNuts
1

In der Tat funktioniert SET TEST_VARIABLE = value nur für den aktuellen Prozess und SETXist daher erforderlich. Ein kurzes Beispiel für das dauerhafte Speichern einer Umgebungsvariablen auf Benutzerebene.

  1. In cmd , SETX TEST_VARIABLE etc. Noch nicht angewendet ( echo %TEST_VARIABLE%zeigt %TEST_VARIABLE%,
  2. Schnelle Überprüfung: cmd öffnen, echo %TEST_VARIABLE%zeigt etc.
  3. GUI-Prüfung: Systemeigenschaften -> Erweitert -> Umgebungsvariablen -> Benutzervariablen für -> Sie sollten Varible TEST_VARIABLE mit Wert sehen etc.
Alexei
quelle
0
:: Sets environment variables for both the current `cmd` window 
::   and/or other applications going forward.
:: I call this file keyz.cmd to be able to just type `keyz` at the prompt 
::   after changes because the word `keys` is already taken in Windows.

@echo off

:: set for the current window
set APCA_API_KEY_ID=key_id
set APCA_API_SECRET_KEY=secret_key
set APCA_API_BASE_URL=https://paper-api.alpaca.markets

:: setx also for other windows and processes going forward
setx APCA_API_KEY_ID     %APCA_API_KEY_ID%
setx APCA_API_SECRET_KEY %APCA_API_SECRET_KEY%
setx APCA_API_BASE_URL   %APCA_API_BASE_URL%

:: Displaying what was just set.
set apca

:: Or for copy/paste manually ...
:: setx APCA_API_KEY_ID     'key_id'
:: setx APCA_API_SECRET_KEY 'secret_key'
:: setx APCA_API_BASE_URL   'https://paper-api.alpaca.markets'
gseattle
quelle