为什么这个 msiexec.exe 命令在 powershell 中不起作用? [英] Why doesn't this msiexec.exe command work in powershell?

查看:43
本文介绍了为什么这个 msiexec.exe 命令在 powershell 中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 powershell 在高级安装程序生成的安装程序调用的脚本中执行以下命令.问题在于,当脚本执行时,它在调用 MSIEXEC.exe 时窒息.更具体地说,它会显示 msiexec 帮助屏幕的 Windows 对话框.

I am trying to execute the following command through powershell, in a script invoked by an Advanced Installer generated installation program. The problem is that when the script executes, it chokes on a call to MSIEXEC.exe. More specifically, it puts up a windows dialog of the msiexec help screen.

好吧,也许它不喜欢高级安装程序执行它的方式.所以我采取了导致问题的实际路线:

Ok so maybe it doesn't like the way advanced installer is executing it. So I take the actual line that is causing problems:

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'

当我直接在 powershell 中执行这个时,我仍然得到同样愚蠢的帮助屏幕.我已经尝试了这个命令行的所有可能的变体:

And when I execute this directly in powershell, I still get the same stupid help screen. I have tried every conceivable variation of this command line:

  • /a 和/passive 而不是/i 和/q
  • 带双引号
  • 带单引号
  • 未加引号的 msi
  • 在管理员提升的 shell 中
  • 在普通权限 shell 中
  • 位于桌面上的 msi 而不是临时文件夹
  • 如果已经安装,则使用/x 进行卸载

在所有情况下,我都会看到该死的帮助"对话框.唯一似乎有所不同的是我是否省略了 INSTALLLOCATION 和 ADDLOCAL 选项.(这些显然是按照此处找到的无人值守安装第 2 部分"使用的:https://docs.mongodb.com/tutorials/install-mongodb-on-windows/).在这种情况下,它只是安静地退出而不安装任何东西.

In all cases, I get the damnable "help" dialog. The only thing that appears to make a difference is if I leave off the INSTALLLOCATION and ADDLOCAL options. (These are apparently used as per "Unattended Installation part 2" found here: https://docs.mongodb.com/tutorials/install-mongodb-on-windows/). In that case it just exits quietly without installing anything.

老实说,我整个下午都在用头撞墙.

I'm honestly at my wits' end having been beating my head against the wall on this all afternoon.

顺便说一句,我以如此荒谬的方式安装 mongo 的原因是我需要一种方法来为我公司的产品安装一个单一安装的系统.这取决于 Mongo,我们必须让它作为服务器运行并使用身份验证,所以我必须有脚本来创建管理员和数据库用户并将其置于身份验证模式.由于我需要知道 mongo 的安装位置(以执行 mongod.exe 和 mongo.exe),因此我需要先向用户查询位置,然后将安装位置传递给 mongo 安装程序.如果我在这里完全偏离轨道,请告诉我有更好的方法.谢谢

By the way, the reason I'm installing mongo in such an absurd way is I need a method of having a single-install system for my company's product. It depends on Mongo, and we have to have it run as a server and use authentication, so I have to have scripts to create the admin and database user and put it into authenticated mode. Since I needed to know where mongo was installed (to execute mongod.exe and mongo.exe) I need to query the user first for the location, then pass on the install location to the mongo installer. If I'm completely off the rails here please let me know that there's a better way. Thanks

已我忘了提及我编写了完整的 powershell 脚本并在尝试通过高级安装程序执行之前对其进行了测试.该脚本一直有效,直到我尝试通过安装程序运行它.奇怪的是我现在手动执行命令还是不行.

EDITED: I forgot to mention I wrote my complete powershell script and tested it before trying to execute it through advanced installer. The script worked until I tried to run it through the installer. Strange that I still can't execute the command though manually now.

推荐答案

似乎为了将带有嵌入空格的路径传递给msiexec,您必须在它们周围使用显式嵌入式 ..." 引用.

It seems that in order to pass paths with embedded spaces to msiexec, you must use explicit embedded "..." quoting around them.

在你的情况下,这意味着而不是通过
INSTALLLOCATION='C:\Program Files\MongoDB\Server\3.4\',你必须通过 INSTALLLOCATION='C:\Program Files\MongoDB\Server\3.4\";'[1]

In your case, this means that instead of passing
INSTALLLOCATION='C:\Program Files\MongoDB\Server\3.4\', you must pass INSTALLLOCATION='"C:\Program Files\MongoDB\Server\3.4\\"'[1]

注意路径末尾嵌入的"..."和额外的\,以确保\"单独不会被误认为 escaped " by msiexec(尽管它也可以在没有额外的 \ 的情况下工作).

Note the embedded "..." and the extra \ at the end of the path to ensure that \" alone isn't mistaken for an escaped " by msiexec (though it may work without the extra \ too).

综合起来:

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'

警告:

  • 这种嵌入式引用技术依赖于长期存在但破坏的 PowerShell 行为 - 请参阅这个答案;如果它得到修复,该技术将停止工作;相比之下,
    --% 下面显示的方法将继续工作.

  • This embedded-quoting technique relies on longstanding, but broken PowerShell behavior - see this answer; should it ever get fixed, the technique will stop working; by contrast, the
    --% approach shown below will continue to work.

一种无变通、面向未来的方法是使用 Native 模块(在 PSv5+ 中,使用 Install-Module Native 安装来自 PowerShell Gallery),它在内部补偿所有损坏的行为并允许按预期传递参数;也就是说,只需在原始命令前加上 ie 就足够了:

A workaround-free, future-proof method is to use the PSv3+ ie helper function from the Native module (in PSv5+, install with Install-Module Native from the PowerShell Gallery), which internally compensates for all broken behavior and allows passing arguments as expected; that is, simply prepending ie to your original command would be enough:

# 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'


替代方案是坚持原始引用并使用--%停止解析符号,但请注意,这意味着您不能在所有后续参数中使用 PowerShell 变量:


The alternative is to stick with the original quoting and use --%, the stop-parsing symbol, but note that this means that you cannot use PowerShell variables in all subsequent arguments:

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'


请注意,msiexec 尽管具有 CLI(命令行界面),但它是一个 GUI 子系统应用程序,因此它默认异步运行;如果您希望同步运行它,请使用
Start-Process -Wait
:


Note that msiexec, despite having a CLI (command-line interface), is a GUI-subsystem application, so it runs asynchronously by default; if you want to run it synchronously, use
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.

请注意,参数列表字符串 $msiArgsStart-Process 用作 as-is 作为命令行的一部分用于调用目标程序(msiexec),即:

Note that the argument-list string, $msiArgs, is used as-is by Start-Process as part of the command line used to invoke the target program (msiexec), which means:

  • 只能使用(嵌入的)双引号.

  • 使用 "..." 与嵌入的 " 转义为 `" 以在字符串中嵌入 PowerShell 变量和表达式.
  • use "..." with embedded " escaped as `" to embed PowerShell variables and expressions in the string.

然而,相反,不需要部分引用参数的解决方法.

conversely, however, no workaround for partially quoted arguments is needed.

尽管 Start-Process 在技术上支持将参数单独作为数组传递,但由于长期存在的错误,最好避免这种情况 -请参阅 GitHub 问题 #5576.

Even though Start-Process technically supports passing the arguments individually, as an array, this is best avoided due to a longstanding bug - see GitHub issue #5576.

[1] INSTALLLOCATION='C:\Program Files\MongoDB\Server\3.4\' 不起作用的原因是 PowerShell 通过 " 转换参数;..."-引用它整体msiexec 无法识别;具体来说,在这种情况下传递给 msiexec 的是:
"INSTALLLOCATION=C:\Program Files\MongoDB\Server\3.4\"

[1] The reason that INSTALLLOCATION='C:\Program Files\MongoDB\Server\3.4\' doesn't work is that PowerShell transforms the argument by "..."-quoting it as a whole, which msiexec doesn't recognize; specifically, what is passed to msiexec in this case is:
"INSTALLLOCATION=C:\Program Files\MongoDB\Server\3.4\"

这篇关于为什么这个 msiexec.exe 命令在 powershell 中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆