【问题标题】:Installing all .msi files within a folder在文件夹中安装所有 .msi 文件
【发布时间】:2018-12-29 03:01:22
【问题描述】:

我正在尝试编写一个我从 python 脚本启动的 powershell 脚本,该脚本将允许我通过并安装包含在某个文件夹中的每个 .msi 文件。

这是我目前所拥有的:

$msiFiles = Get-ChildItem -Path "***PATH TO FOLDER***" -Recurse -Include *.msi

foreach($file in $msiFiles)
{

    Write-Host "$file is being installed"
    Start-Process "msiexec.exe" -arg "/I $file /qb ADDLOCAL=ALL ALLUSERS=TRUE" -Wait
    Write-Host "$file is finished being installed"


}

我想以静默模式安装这些 msi,因此我看不到或不需要 ant GUI 交互。当它要安装msi时,我会从安装程序中弹出一个带有所有可能用于安装东西的命令,但它实际上并没有安装它。

在静默模式下安装这些的正确命令是什么?

【问题讨论】:

  • 在 Start-Process 行之前的代码中执行此操作Write-Host "/I $file /qb ADDLOCAL=ALL ALLUSERS=TRUE"。请在您的问题中输入一份输出样本。
  • 你试过搜索吗?我想不是很难找到。看看这个来自多项式stackoverflow.com/questions/8560166/… 的答案
  • @Theo 是的,我已经尝试使用该链接中的步骤,但仍然得到我上面描述的相同弹出窗口
  • 请注意,ALLUSERS 应设置为 0 或 1(或 2 与 MSIINSTALLPERUSER),而不是 TRUE。此外,ADDLOCAL=ALL 可能好也可能不好,具体取决于给定 .msi 文件中的功能。 (不过,这些都不是语法无效的,所以不会导致你问的问题。)
  • 不是这样的答案,但我只想告诉您:The Windows Installer PowerShell Module on github.com - 它提供 MSI cmdlet(向下滚动以获取描述,使用发布标签供下载或阅读说明)。我还没有真正测试过它,但它来自Heath Stewart - Microsoft 高级软件工程师 (github)。

标签: python powershell windows-installer


【解决方案1】:

通常,如果调用 msiexec 只显示一个描述命令行语法的对话框,则表示存在语法问题

语法错误的可能来源是您用作-arg 参数的"..." 字符串(全名:-Args-ArgumentList)具有$file嵌入其中没有嵌入引用

也就是说,如果 $file 的值嵌入了 空格,例如(例如,C:\Msi Installers\foo.msi),则生成的 msiexec 命令将在语法上无效,因为路径的空格分隔标记每个都被视为一个参数。

Bill_Stewart's helpful answer 向您展示了如何$file 周围使用内嵌引用 来解决这个问题,方法是将其包含在`" 中(` 是 PowerShell 的转义字符)。

如果您坚持将参数作为 单个 字符串传递,您可以使用:

Start-Process msiexec.exe -Args "/I `"$file`" /qb ADDLOCAL=ALL ALLUSERS=TRUE" -Wait

然而,可以说,更简洁不要将 单个、类似命令行的字符串作为 only 参数传递,而是改为将参数作为数组元素传递,这确实是-ArgumentList / -Args 被设计为接受的(其参数类型为[string[]]): p>

Start-Process msiexec.exe -Args /I, `"$file`", /qb, ADDLOCAL=ALL, ALLUSERS=TRUE -Wait

注意 $file 如何仍然通过嵌入式引用传递,不幸的是 由于a bug in Start-Process 是必需的(从 Windows PowerShell 开始v5.1 / PowerShell 核心 v7.1);不过,看起来这个错误不会得到修复,但链接的 GitHub 报告建议引入具有正确行为的新
-ArgumentArray 参数。


您也可以提前中建立参数数组;注意这是如何在 expression 模式下完成的(语法更像常规编程语言),所以数组元素 all 需要引用;还要注意我是如何使用 single 引号来定义 literal 参数的:

# Create the array of arguments to pass to msiexec
$msiArgs = 
  '/I',
  "`"$file`"",      #`# !! enclosing in `"...`" is needed due to the bug mentioned above
  '/qb',
  '/ADDLOCAL=ALL',
  'ALLUSERS=TRUE'

Start-Process msiexec.exe -Args $msiArgs -Wait      

【讨论】:

    【解决方案2】:

    试试这个方法:

    $msiFiles = Get-ChildItem -Path "***PATH TO FOLDER***" -Recurse -Include *.msi
    
    foreach ( $file in $msiFiles ) {
      $fullPath = $file.FullName
      Write-Host "'$fullPath' is being installed"
      Start-Process -FilePath msiexec.exe -ArgumentList "/I `"$fullPath`"","/qb","ADDLOCAL=ALL","ALLUSERS=TRUE" -Wait
      Write-Host "$fullPath is finished being installed"
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      相关资源
      最近更新 更多