我有一台在 Windows XP 主机上安装了 Windows XP 的 VirtualBox 机器。
我如何将 VirtualBox 作为服务启动,这样我就可以获得虚拟机,而不必启动 VirtualBox 来访问我的虚拟机(通过网络上的 VNC)?
我发现 VirtualBox Manage 可能是可行的方法,但由于我是初学者,所以我不知道从哪里开始。
有任何想法吗?
答案1
创建快捷方式C:\Program Files\innotek VirtualBox\VBoxManage.exe
在引号后输入:startvm <your virtual machine name>
例子:
“C:\Program Files\innotek VirtualBox\VBoxManage.exe” startvm XP
将快捷方式复制/移动到您的启动文件夹。
附言:如果你想延迟虚拟机,直到你的系统完全启动,你可以在 XP 中通过以下方式执行此操作启动延迟器。
答案2
请注意,目前接受的答案 (Molly7244) 实际上是在您登录时启动虚拟机 - 而不是在您启动机器时。换句话说,它不是一项服务。
对于在机器启动时运行的实际服务,我使用两个脚本(最初来自这里) 与 cygwin (cygrunsrv) 结合使用。利用本页其他地方提到的 VBoxHeadless 模式。
第一个脚本通过 VBoxHeadless 运行您的 VM;它从环境变量中获取要运行的正确 VM 的名称(以及其他信息,例如您的 VBOX 主目录)。第二个脚本为特定 VM 安装服务(通过使用 cygrunsrv 调用第一个脚本并设置正确的环境变量)。最后是第三个文件,其中包含常用函数。如果将所有这些文件一起放入一个目录中,则可以像这样安装新的 VM:
$ VBOX_USER_HOME="/path/to/.VirtualBox/" vboxd-install MyVMName 3333
然后使用“net start vboxd-MyVMName”或“cygrunsrv -S vboxd-MyVMName”启动服务。
这是虚拟机运行脚本“vboxd”:
#!/bin/bash
# from http://forums.virtualbox.org/viewtopic.php?f=1&t=23536
##
## Manages start / stop of VirtualBox virtual machines
##
## load common functions
basedir="$(readlink -f $(dirname $0))"
source "$basedir/.libcommon" || exit 1
## parse arguments
parseArg vmName "$1" "$VBOXD_VM_NAME"
parseArg vmPort "$2" "$VBOXD_VM_PORT"
VBOX_INSTALL_PATH="$(cygpath "$VBOX_MSI_INSTALL_PATH")"
## define signal handler
function onHalt {
warn "Stopping virtual machine '$vmName'"
"$VBOX_INSTALL_PATH/VBoxManage" controlvm "$vmName" savestate
exit 0
}
## install signal handler; cygrunsrv uses SIGTERM by default
trap 'onHalt' TERM
## hardcode this path if you like; it's required for VBox* utils to
## find the correct VirtualBox.xml config file and is usually set
## during a call to vboxd-install.
#export VBOX_USER_HOME="$USERPROFILE\\.VirtualBox"
## default VBoxHeadless port specification
portSpec="-e \"TCP/Ports=$vmPort\""
## determine vm state
info "Querying virtual machine '$vmName' state"
vmState=$( \
"$VBOX_INSTALL_PATH/VBoxManage" showvminfo "$vmName" \
| grep '^State:' \
| sed 's/State: *//' )
info "Virtual machine '$vmName' is $vmState"
## if vm state is saved, we can't specify port without an exception,
## as port spec requires modification of the (immutable) saved machine
## state. See http://www.virtualbox.de/ticket/3609
if [ "${vmState##saved}" != "$vmState" ]; then
## state is saved; clear port specification
warn "Port specification is not allowed for saved vms"
portSpec=""
fi
## start the VM
info "Starting virtual machine '$vmName' on port $vmPort"
"$VBOX_INSTALL_PATH/VBoxHeadless" -s "$vmName" $portSpec &
## record pid of VBoxHeadless child process and wait on it
pid="$!"
info "Waiting on VBoxHeadless child process $pid"
wait "$pid"
这是安装程序脚本“vboxd-install”:
#!/bin/bash
# http://forums.virtualbox.org/viewtopic.php?f=1&t=23536
##
## Registers a VirtualBox virtual machine to start as a service via cygrunsrv
##
## load common functions
basedir="$(readlink -f $(dirname $0))"
source "$basedir/.libcommon" || exit 1
## test for presence of cygrunsrv utility
if [ ! -x "$(which cygrunsrv)" ]; then
die "Utility 'cygrunsrv' is not in path"
fi
## test VirtualBox configuration
if [ -z "$VBOX_USER_HOME" ]; then
die "Required environment variable 'VBOX_USER_HOME' is undefined. " \
"Please ensure this variable is set to point to the directory " \
"containing your VirtualBox.xml configuration file."
fi
configFile=$(cygpath -u "$VBOX_USER_HOME\\VirtualBox.xml")
if [ ! -e "$configFile" ]; then
die "VirtualBox configuration file '$(cygpath -w $configFile)' not found"
fi
## parse arguments
parseArg vmName "$1"
parseArg vmPort "$2"
parseArg vmUser "$3" "SYSTEM"
## if vmUser is not SYSTEM, update userSpec
userSpec="--interactive"
if [ "$vmUser" != "SYSTEM" ]; then
## "interactive" option disallowed when user is specified
userSpec="--user \"$vmUser\""
fi
## install the service
cygrunsrv \
--install "vboxd-$vmName" \
--path "$basedir/vboxd" \
--env "VBOXD_VM_NAME=$vmName" \
--env "VBOXD_VM_PORT=$vmPort" \
--env "VBOX_USER_HOME=$VBOX_USER_HOME" \
--desc "VirtualBox virtual machine '$vmName' on port $vmPort" \
$userSpec \
--type auto \
--termsig TERM \
--shutsig TERM \
--neverexits \
--preshutdown \
|| die "Failed to install service"
最后,这是这两个文件引用的“.libcommon”脚本:
# -*-shell-script-*-
# from http://forums.virtualbox.org/viewtopic.php?f=1&t=23536
SCRIPT="$(basename $0)"
BASEDIR="$(readlink -f $(dirname $0))"
[ -z "$LOGLEVEL" ] && LOGLEVEL=2
[ -z "$LOGDATEFORMAT" ] && LOGDATEFORMAT="%Y-%m-%d %H:%M:%S "
function log {
local now=""
[ -n "$LOGDATEFORMAT" ] && now=$(date +"$LOGDATEFORMAT")
echo "$SCRIPT $now$@" >&2
}
function debug {
[ "$LOGLEVEL" -lt 3 ] && return
log "[DEBUG] $@"
}
function info {
[ "$LOGLEVEL" -lt 2 ] && return
log "[INFO] $@"
}
function warn {
[ "$LOGLEVEL" -lt 1 ] && return
log "[WARN] $@"
}
function error {
log "[ERROR] $@"
}
function die {
error "$@"
exit 1
}
function parseArg {
local _name="$1"
local _value="$2"
local _default="$3"
if [ -z "$_value" ]; then
if [ -z "$_default" ]; then
die "Required argument '$_name' is undefined"
fi
if [ "$_default" = "*EMPTY*" ]; then
_value=""
else
_value="$_default"
fi
fi
debug "$_name=\"$_value\""
eval "$_name=\"$_value\""
}
这个解决方案对我来说非常有效;希望您也能有同样的运气。
答案3
目前看来最简单的答案是虚拟盒虚拟机服务。我还没有尝试过,如果/当我尝试的时候,我会尽量记得来这里更新答案。
答案4
仅提供此作为另一种选择:
使用内置 Windows 命令“sc”创建服务。将其与“vboxheadless”结合使用将带您到达您想要的位置。
未专门使用 vboxheadless 进行测试,但我确实创建了一个运行 calc.exe 的测试服务。您应该执行以下操作:
sc create servicenamehere start= auto binPath= "C:\path\to\vboxheadless.exe --startvm name"
有关更多信息,请参阅 sc 的文档。注意:等号后面的空格是故意的。