如何等待VirtualBox完成加载以在Windows批处理中执行下一个命令?

时间:2013-06-25 15:35:30

标签: shell command-line batch-file virtualbox wait

我在编写最近的CMD批处理文件时遇到了一些麻烦。这应该是在工作中启动我的开发环境,并且在大多数情况下它可以工作:

@echo off
start cmd.exe
start notepad++.exe
start sublime_text.exe
start outlook.exe
start communicator.exe
start "* Starting VirtualBox ..." virtualbox.exe
start sh.exe
start firefox.exe

我面临的挑战是我想启动git-bash,(sh.exe)但是在企业配置虚拟机中必须启动并运行vagrant,一个基于shell的虚拟机管理器才能正确加载。因此,由于这种依赖性,我需要virtualbox.exe启动并完全加载(我们不需要“启动”和框)然后启动git-bash shell(sh.exe)。

我已经搜索过,但没有找到如何做到这一点。我一直在推荐结果:

  • /等待
  • ping localhost(n)次以创建计时器hack

这些选项的问题是/ wait在VirtualBox关闭之前不会移动到下一个命令 - 这不是我想要的。第二个选项是基于时间的等待,在这种情况下也无法解决我的问题。

我做错了什么?

4 个答案:

答案 0 :(得分:5)

哇!感谢 paulm 的灵感。

找到了一个很好的机会!

我正在使用命令浏览build-it guest OS属性:

 VBoxControl guestproperty enumerate -patterns *

我发现了一个很好的属性“ / VirtualBox / GuestInfo / OS / LoggedInUsers

在guest虚拟机操作系统启动期间,此属性将从“No value set!”更改为通过值“0”到“1”(如果用户自动登录)。 适用于Windows和Linux。

>VBoxManage guestproperty get "WIN7_32" "/VirtualBox/GuestInfo/OS/LoggedInUsers"
No value set!

>VBoxManage guestproperty get "WIN7_32" "/VirtualBox/GuestInfo/OS/LoggedInUsers"
Value: 0

>VBoxManage guestproperty get "WIN7_32" "/VirtualBox/GuestInfo/OS/LoggedInUsers"
Value: 1

因此,您无需在客户操作系统上添加任何内容以启动!甜!

您甚至可以使用等待

VBoxManage guestproperty wait "WIN7_32" "/VirtualBox/GuestInfo/OS/LoggedInUsers"

但请记住,一旦客户操作系统到达欢迎屏幕,该命令将返回0

答案 1 :(得分:1)

正如您所观察到的,VirtualBox / VBoxManage进​​程将在VM实际打开后返回并退出。虽然您可以做的一件事是指示VirtualBox运行命令并检查退出代码,但是没有一种方法可以在开始时挂接guest虚拟机。我会在启动来宾VM后立即在您的批处理文件脚本中插入此代码,但在您想要启动sh.exe之前:

:CheckVBox
VBoxManage guestcontrol Win8 exec --image c:\Windows\System32\ipconfig.exe --wait-exit --username Goyuix --password VirtualBoxRox
IF NOT ERRORLEVEL 0 (
  REM Do something to sleep here, pinging localhost or timeout
  GOTO CheckVBox
)
REM VM Ready, go ahead and fire up other apps that depend on it

注意:您需要拥有PATH环境变量中VBoxManage可执行文件的路径。在Windows上,它通常是:C:\ Program Files \ Oracle \ VirtualBox

当然,您可能想要一些更健壮的东西,只需运行ipconfig来检测VM是否真的准备就绪。我不确定你会依赖哪些服务等,但这可能足以让你超越驼峰,当然可以适应检查服务状态等。

答案 2 :(得分:1)

“最佳”方法是在主机上使用VBoxManage并使用属性在客户机上使用VBoxControl。

其工作方式是主机将等待设置属性,并且当您认为机器已“加载”时,客户机将设置此属性。对我来说,我只需从登录脚本中设置属性。

所以在我的Linux主机上我说:

VBoxManage guestproperty wait My_Virtual_Machine_Name Wait_For_Logon_Event

这将永远等待/阻止,如果您愿意,可以添加超时。

然后在登录脚本或机器启动脚本中的Windows Guest上执行:

VBoxControl guestproperty set Wait_For_Logon_Event Event_Now_Set

然后导致执行在主机端继续:

Name: Wait_For_Logon_Event, value: Event_Now_Set, flags:

答案 3 :(得分:0)

LoggedInUsers似乎不再可以与wait(VirtualBox 5.2.22)一起使用,但是get可以使用。所以我切换到另一个属性:

VBoxManage guestproperty wait <host> "/VirtualBox/GuestInfo/OS/NoLoggedInUsers"

由于我们仅在等待该属性可用,因此您可以使用/VirtualBox/GuestInfo/OS下的任何guestproperties,这些属性对于非运行中的计算机不可用。您可以通过以下方式了解他们的身份

vboxmanage guestproperty enumerate <host> | grep GuestInfo/OS

其中<host>应该正在运行。然后将该列表与未运行计算机的列表进行比较。