我在Windows XP主机上有一台装有Windows XP的VirtualBox机器。
如何将VirtualBox作为服务启动,这样我就可以获取虚拟机,而不必启动VirtualBox即可访问虚拟机(通过网络上的VNC)?
我发现VirtualBox Manage可能是可行的方法,但是由于我是初学者,因此我不知道从哪里开始。
有任何想法吗?
我在Windows XP主机上有一台装有Windows XP的VirtualBox机器。
如何将VirtualBox作为服务启动,这样我就可以获取虚拟机,而不必启动VirtualBox即可访问虚拟机(通过网络上的VNC)?
我发现VirtualBox Manage可能是可行的方法,但是由于我是初学者,因此我不知道从哪里开始。
有任何想法吗?
Answers:
创建快捷方式以 C:\Program Files\innotek VirtualBox\VBoxManage.exe
在引号后输入: startvm <your virtual machine name>
例:
“C:\Program Files\innotek VirtualBox\VBoxManage.exe” startvm XP
将快捷方式复制/移动到启动文件夹。
ps:如果要将虚拟机延迟到完全引导系统之前,可以通过XP中的Startup Delayer来执行。
请注意,当前接受的答案(Molly7244)实际上是在登录时启动VM,而不是在启动计算机时启动。换句话说,它不是服务。
对于在机器启动时运行的实际服务,我将两个脚本(最初是从此处开始)与cygwin(cygrunsrv)结合使用。如本页其他位置所述,使用VBoxHeadless模式。
第一个脚本通过VBoxHeadless运行您的VM。它从环境变量中获取要运行的正确VM的名称(以及其他信息,例如VBOX主目录)。第二个脚本为特定的VM安装服务(通过使用cygrunsrv调用设置了正确的env。vars的第一个脚本)。最后是包含通用功能的第三个文件。如果将所有这些放到一个目录中,则可以像这样安装新的vm:
$ VBOX_USER_HOME="/path/to/.VirtualBox/" vboxd-install MyVMName 3333
然后使用“ net start vboxd-MyVMName”或“ cygrunsrv -S vboxd-MyVMName”启动服务。
这是运行VM的脚本“ 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\""
}
该解决方案对我来说非常有用;希望你也会有同样的运气。
目前看来,最简单的答案是VBoxVMService。我还没有尝试过,如果有的话,我会尽量记住来这里并更新答案。
在VBoxVMService上达成协议。设置起来真的很容易,并且似乎运行良好。您可以在此处找到如何进行设置:
****编辑****根据下面的请求,链接的摘要。尽管该解决方案对我有用,但值得感谢的是Peter Upfold- http: //peter.upfold.org.uk/
[设定]
ServiceName = VBoxVmService
VBOX_USER_HOME = C:\ Users \ Administrator.VirtualBox
RunAsUser =。\ Administrator
UserPassword = enteryourpassword此处
RunWebService =否
暂停关机= 5000
[Vm0] VmName = VirtualBox中的虚拟机名称
ShutdownMethod =保存状态
自动启动=是
用正确的用户主目录中的.VirtualBox文件夹以及RunAsUser和UserPassword指令替换VBOX_USER_HOME,并在VmName中的VirtualBox应用程序中设置目标虚拟机的名称。您还可以在[Vm0]之后向其他虚拟机添加其他[Vmx]节,以在计算机启动时启动。
当您对配置感到满意时,从启用管理员的命令提示符下,运行以下命令来安装服务。安装服务后,您可以从INI文件中删除用户密码,因为该密码已保存在“服务”配置中:
C:\ vms \ VmServiceControl.exe -i
现在,您必须重新引导计算机,然后才能尝试首次启动该服务,否则它将无法找到VM。
重新启动后,该服务应启动(受“自动(延迟启动)”延迟的影响),并且您的VM将在启动时启动。
只是提供此作为另一种选择:
使用内置的Windows命令'sc'创建服务。将其与“ vboxheadless”结合使用将使您到达想要的位置。
未经过vboxheadless专门测试,但是我确实创建了运行calc.exe的测试服务。您应该这样做:
sc create servicenamehere start= auto binPath= "C:\path\to\vboxheadless.exe --startvm name"
有关更多信息,请参考sc的文档。注意:等号后的空格是故意的。
如果vboxd脚本给您带来了像我一样多的麻烦,那么您可能想尝试一下;这是一个相当简单的解决方案,在Perl中实现,提供了相同的功能。具体来说,VM随系统启动(假设服务设置为自动启动,这是默认设置),然后在停止服务时干净地关闭。
与vboxd解决方案的主要区别在于,根据我的经验,该脚本不易于处理,它没有将VRDE端口设置传递给VBoxHeadless,并且VM关闭是通过“ acpipowerbutton”而不是“ savestate”处理的。
如果这不符合您的目的,则很容易进行更改;在第一种情况下,将'-e“ TCP / Ports = [,port ...]”'添加到VBoxHeadless命令行字符串($ cmd),在第二种情况下,只需在以下命令中将“ acpipowerbutton”更改为“ savestate” SIGTERM处理程序。
这是Perl脚本:
#!/usr/bin/perl
# Service wrapper for VirtualBox VM.
use strict;
# Windows-style path pointing to your VirtualBox home directory
# (i.e., where your VirtualBox.xml lives)
my $vboxhome = 'c:\\Documents and Settings\\Aaron\\.VirtualBox';
# Cygwin path pointing to the VirtualBox install directory
my $vboxpath = '/cygdrive/c/Program Files/Oracle/VirtualBox';
# Name or UUID of your virtual machine
my $vmname = '{83dfb4b1-4243-4a07-9d37-9df5573792d8}';
$ENV{'VBOX_USER_HOME'} = $vboxhome;
my $exit_handler = sub {
print "Caught SIGTERM; shutting down VM.\n";
exec("'$vboxpath/VBoxManage.exe' controlvm $vmname acpipowerbutton");
};
$SIG{TERM} = $exit_handler;
print "[debug] pid $$\n";
# Command line for VBoxHeadless - add your VRDE port here if you want one
my $cmd = "'$vboxpath/VBoxHeadless.exe' --startvm $vmname 2>&1 1>/dev/null";
print "[debug] $cmd\n";
system($cmd);
print "VM died unexpectedly; exiting.\n";
这是我用来安装Windows服务的cygrunsrv命令行:
cygrunsrv --install '<service-name>' --desc '<description>' \
--path '/usr/bin/perl' --args '<full-path-to-service-script>' \
--chdir '<path-to-service-script-dir>' --termsig TERM --shutsig TERM \
--preshutdown --interactive
从那里开始,只需要发出'sc start <service-name>',就可以了-记住,默认情况下,cygrunsrv服务登录到/ var / log / <service-name> .log,因此,如果有任何不当行为,这是查找原因的第一位。
要记住的一件事是,当以这种方式运行VM时,它将在内置的SYSTEM帐户下运行,而不是在您自己的帐户下运行。在这种情况下,当虚拟机作为服务运行时,您将无法通过VirtualBox控制台管理该虚拟机。它似乎处于“关闭电源”状态,您将无法进入其设置。(不建议在虚拟机作为服务运行时尝试打开电源-我不知道会发生什么,但是充其量是空无一人,更糟糕的是,它会使虚拟机陷入困境。)如果您需要更改VM的设置或访问控制台,请先停止该服务(并等待VBoxHeadless.exe退出),然后像往常一样在VirtualBox控制台中对其进行配置/启动。
您可能可以通过安装第二个交互式服务来运行VirtualBox控制台来解决此问题。因为那样也可以在SYSTEM帐户下运行控制台,所以它很可能能够查看和管理正在运行的VM。我自己不需要这样做,所以我不确定它是否可以工作,但是我不知道为什么不行。(如果您尝试过,我很乐意对此答案发表评论,让我知道它为您带来的效果。谢谢!)
希望这可以帮助!
vboxd-install
这很有用,因为它可以方便地隐藏cygrunsrv的参数详细信息。不过,我同意,这acpipowerbutton
是比更好的“停止”选择savestate
。