MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Warum funktioniert dieser msiexec.exe-Befehl nicht in Powershell?

Es scheint, dass um Pfade mit eingebetteten Leerzeichen zu übergeben zu msiexec , müssen Sie explizit embedded verwenden "..." um sie herum zitieren.

In Ihrem Fall bedeutet dies, dass statt
INSTALLLOCATION='C:\Program Files\MongoDB\Server\3.4\' müssen Sie INSTALLLOCATION='"C:\Program Files\MongoDB\Server\3.4\\"' übergeben

Beachten Sie den eingebetteten "..." und den zusätzlichen \ am Ende des Pfads, um sicherzustellen, dass \" allein wird nicht mit einem Entkommenen verwechselt " durch msiexec (obwohl es ohne den zusätzlichen \ funktionieren könnte auch).

Um alles zusammenzufassen:

msiexec.exe /q /i `
  'C:\Users\ADMINI~1\AppData\Local\Temp\mongo-server-3.4-latest.msi' `
  INSTALLLOCATION='"C:\Program Files\MongoDB\Server\3.4\\"' ADDLOCAL='all'

Vorbehalt :

  • Diese Technik des eingebetteten Zitierens beruht auf einer altbewährten, aber kaputten Technik PowerShell-Verhalten - siehe diese Antwort ; sollte es jemals repariert werden, funktioniert die Technik nicht mehr; im Gegensatz dazu die
    --% Der unten gezeigte Ansatz wird weiterhin funktionieren.

  • Eine Workaround-freie, zukunftssichere Methode ist die Verwendung von PSv3+ ie Hilfsfunktion aus dem Native Modul (In PSv5+ mit Install-Module Native installieren aus der PowerShell-Galerie ), die intern alles fehlerhafte Verhalten kompensiert und erlaubt die Übergabe von Argumenten wie erwartet; das heißt, einfach ie voranstellen zu Ihrem ursprünglichen Befehl würde ausreichen:

# No workarounds needed with the 'ie' function from the 'Native' module.
ie msiexec.exe /q /i 'C:\Users\ADMINI~1\AppData\Local\Temp\mongo-server-3.4-latest.msi' INSTALLLOCATION='C:\Program Files\MongoDB\Server\3.4\' ADDLOCAL='all'

Die Alternative ist, beim ursprünglichen Zitat zu bleiben und --% zu verwenden , das Stop-Parsing-Symbol , aber beachten Sie, dass dies bedeutet, dass Sie PowerShell-Variablen nicht in allen nachfolgenden Argumenten verwenden können:

msiexec.exe /q /i `
  'C:\Users\ADMINI~1\AppData\Local\Temp\mongo-server-3.4-latest.msi' `
   --% INSTALLLOCATION="C:\Program Files\MongoDB\Server\3.4\\" ADDLOCAL='all'

Beachten Sie, dass msiexec , obwohl es eine CLI (Befehlszeilenschnittstelle) hat, ist eine GUI -subsystem-Anwendung, sodass sie asynchron ausgeführt wird standardmäßig; wenn Sie es synchron ausführen möchten , verwenden Sie
Start-Process -Wait
:

$msiArgs = '/q /i "C:\Users\ADMINI~1\AppData\Local\Temp\mongo-server-3.4-latest.msi" INSTALLLOCATION="C:\Program Files\MongoDB\Server\3.4\\" ADDLOCAL=all'

$ps = Start-Process -PassThru -Wait msiexec -ArgumentList $msiArgs

# $ps.ExitCode contains msiexec's exit code.

Beachten Sie, dass die Argumentlistenzeichenfolge $msiArgs , wird so wie es ist verwendet durch Start-Process als Teil der Befehlszeile zum Aufrufen des Zielprogramms (msiexec ), was bedeutet:

  • nur (eingebettete) doppelte Anführungszeichen verwendet werden.

    • benutze "..." mit eingebettetem " als `" maskiert um PowerShell-Variablen und -Ausdrücke in den String einzubetten.
  • Umgekehrt ist jedoch keine Problemumgehung für teilweise in Anführungszeichen gesetzte Argumente erforderlich.

Obwohl Start-Process unterstützt technisch die Übergabe der Argumente einzeln , als Array , wird dies aufgrund eines seit langem bestehenden Fehlers am besten vermieden – siehe GitHub issue #5576 .