【问题标题】:Why does Chocolatey fail to install when provisioning a Windows 7 VM using Vagrant?为什么在使用 Vagrant 配置 Windows 7 VM 时无法安装 Chocolatey?
【发布时间】:2016-01-07 22:52:50
【问题描述】:

我正在尝试在 Windows 8.1 主机上使用 Packer (v.0.8.6)Vagrant (v.1.8.1)VirtualBox (v.5.0.10)Chocolatey (v.0.9.9.11) 自动创建 Windows 7 开发环境。

我已经设法使用 Packer 创建了基本的 Windows 7 SP1 机器,并且我正在尝试使用 vagrant up 创建带有 Vagrant 的虚拟机。我要做的第一件事是安装 Chocolatey,这样我就可以轻松地配置其他软件。

但是。我一直没有成功。我在我的 Vagrantfile 中尝试了各种咒语。以下是内容。

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
  config.vm.box = "windows_7"
  config.vm.provider "virtualbox" do |vb|
    # Display the VirtualBox GUI when booting the machine
    vb.gui = true
  end

  # option 1
  # config.vm.provision "shell", "inline": "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))"

  # option 2
  # config.vm.provision "shell", "path": "./scripts/install-chocolatey.cmd"

  # option 3
  # config.vm.provision "shell", path: "./scripts/install-chocolatey.ps1"
end

# ./scripts/install-chocolatey.cmd
@powershell -NoProfile -ExecutionPolicy Bypass -File "%systemdrive%\vagrant\scripts\install-chocolatey.ps1"

# ./scripts/install-chocolatey.ps1
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

我收到的任何这些选项的错误是:

==> default: Everything is Ok
==> default:
==> default: Files: 76
==> default: Size:       4893948
==> default: Compressed: 1806765
==> default: out-lineoutput : The OS handle's position is not what FileStream expected. Do n
==> default: ot use a handle simultaneously in one FileStream and in Win32 code or another F
==> default: ileStream. This may cause data loss.
==> default:     + CategoryInfo          : NotSpecified: (:) [out-lineoutput], IOException
==> default:     + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Comma
==> default:    nds.OutLineOutputCommand
==> default:

但是,如果我从虚拟机上的 Cmd 或 PowerShell 窗口手动运行选项 1、2 或 3,chocolatey 安装正常。

我在网上搜索了这个错误,它似乎是PowerShell 2 and 3 bug。事实上,如果我在虚拟机上手动安装 PowerShell 4 并运行 vagrant provision 以重新配置它,这些选项将起作用。

但如果是这种情况,为什么我可以手动安装 Chocolatey 而不是通过 Vagrant?我想使用 Chocolately 来升级 PowerShell,因为以自动化方式这样做会更容易。

如何指示 Vagrant 在我的虚拟机上安装 Chocolatey,而无需先将 PowerShell 升级到新版本?


解决方法尝试 1:

我尝试将 VirtualBox 从 5.0.10 降级到 4.3.28 以查看是否存在问题(根据建议)。但是,我无法在我的主机上运行 4.3.28,因为在尝试创建新虚拟机时收到错误消息,即使是开箱即用,也没有打包程序或 vagrant。重新安装 5.0.10 解决了该特定问题。


解决方法尝试 2:

我将 Powershell 2 解决方法脚本 defined here 应用于我的 install-chocolatey.ps1 脚本。完整的内容就变成了:

$bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetField"
$objectRef = $host.GetType().GetField("externalHostRef", $bindingFlags).GetValue($host)

$bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetProperty"
$consoleHost = $objectRef.GetType().GetProperty("Value", $bindingFlags).GetValue($objectRef, @())

[void] $consoleHost.GetType().GetProperty("IsStandardOutputRedirected", $bindingFlags).GetValue($consoleHost, @())
$bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetField"
$field = $consoleHost.GetType().GetField("standardOutputWriter", $bindingFlags)
$field.SetValue($consoleHost, [Console]::Out)
$field2 = $consoleHost.GetType().GetField("standardErrorWriter", $bindingFlags)
$field2.SetValue($consoleHost, [Console]::Out)

iex -Debug ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

这允许 Chocolatey 安装。但是,在我重新启动机器之前,我无法从 Vagrant 供应商或 cmd 行或 PowerShell 窗口发出 choco 语句。但是,一旦重新启动,它们就会变得可用,这会导致配置失败。据我了解,我不需要重新启动机器即可使用 Chocolatey。我应该只需要重新启动外壳。检查 PATH 变量,我发现 Chocolatey 没有被添加到 PATH 中,这可以解释这个问题。

【问题讨论】:

  • Lee Holmes 解决方法可能应该被提升为 Vagrant powershell 配置程序。我可以直接从来宾 powershell 控制台安装 Chocolatey,没问题。

标签: windows vagrant chocolatey


【解决方案1】:

因此,当有一个日志到一个流(例如 stdout),然后是另一个流(例如 stderr)的日志时,您会看到 PowerShell 错误消息,通常涉及将输出写入文件路径。

发生了一个错误,但不幸的是 PowerShell 正在吞噬它并重现其他问题 - 您可以在调用安装 Chocolatey 之前添加 $env:ChocolateyDebug 并查看它是否有助于指出错误发生的位置。

如果我不得不猜测它可能与 Chocolatey 尝试安装 .NET Framework 4.0 并遇到错误有关。在我的 vagrant repo 中,我倾向于将 .Net 4 安装的步骤与 Chocolatey 分开。该仓库位于vagrant-windows-puppet

【讨论】:

  • 在安装 Chocolatey 之前,我已将 $env:ChocolateyDebug = 'true' 添加到 install-chocolatey.ps1 文件中,不幸的是,我在 vagrant 输出中没有看到任何其他错误信息。我也试过$env:ChocolatelyEnvironmentDebug = 'true'。我还确认我在基础映像上安装了 .NET 4.0 和 .NET 4.5。 Chocolatey 不会尝试安装这些,因为它们已经存在,对吧?
  • 您还可以将所有输出重定向到标准输出,这样您就不会收到错误,但您会看到实际的错误。
  • 我尝试将命令包装在Start-Transaction/Stop-Transaction 中。我还尝试通过 2>&1 重定向输出。这两个选项都没有向我显示更多信息,并且我通过 Vagrant 在控制台中收到相同的错误错误消息。
  • 我会尽力为您提供一些您可以尽快尝试的东西。您是否有机会在使用上述存储库时验证它是否发生?
  • 我能够在上述 repo 上重现此行为。
猜你喜欢
  • 1970-01-01
  • 2015-08-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2021-11-27
  • 1970-01-01
  • 2021-07-21
  • 1970-01-01
相关资源
最近更新 更多