如何在Windows XP上将VirtualBox计算机作为服务运行?


13

我在Windows XP主机上有一台装有Windows XP的VirtualBox机器。

如何将VirtualBox作为服务启动,这样我就可以获取虚拟机,而不必启动VirtualBox即可访问虚拟机(通过网络上的VNC)?

我发现VirtualBox Manage可能是可行的方法,但是由于我是初学者,因此我不知道从哪里开始。

有任何想法吗?

Answers:


0

创建快捷方式以 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来执行


它似乎工作正常,是否还有“隐藏”虚拟机窗口的功能,因此它更像Windows服务一样运行?
Jhonny D. Cano -Leftware- 2010年

将VBox作为服务运行不会隐藏窗口。您可以通过AWM将其自动最小化到系统托盘:eusing.com/WindowManager/WindowManager.htm

15
签出“ VBoxHeadless”以启动没有UI的VM。如果要查看VM的屏幕,则需要使用RDP。
Mark Porter 2010年

13
这不是一项服务。这仅在您登录时运行VBox,而不是在打开计算机电源时运行。VBoxHeadless是作为服务运行的方式。请参阅下面的答案(根据Aaron Copley的评论,我将对其进行改进)。
约翰·哈特

答案与作为服务运行无关。启动是在用户登录后发生的,与服务行为完全不同。
Felice Pollano '16

10

请注意,当前接受的答案(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\""
}

该解决方案对我来说非常有用;希望你也会有同样的运气。


4
+1表示“不是服务” ... -1表示链接到解决方案,而不是将其包含在答案中。投票为空。:)考虑修改以包括解决方案,因为链接腐烂不利于此答案的持久性。
亚伦·科普利

8

目前看来,最简单的答案是VBoxVMService。我还没有尝试过,如果有的话,我会尽量记住来这里并更新答案。


1
但它不适用于4.2.x
Archimedes Trajano 2013年

2
@ArchimedesTrajano我已经使用VirtualBox 4.3.6尝试了当前版本(4.1),并且运行良好。该项目的页面声称它“几乎是从头开始重写”的
Melebius

1
是的,昨晚我刚刚对其进行了测试,它可以正常工作!只记得重新启动。
Archimedes Trajano 2014年

4

在VBoxVMService上达成协议。设置起来真的很容易,并且似乎运行良好。您可以在此处找到如何进行设置:

http://www.windows-noob.com/forums/index.php?/topic/4931-have-virtualbox-vms-start-as-a-service-on-a-windows-host/

****编辑****根据下面的请求,链接的摘要。尽管该解决方案对我有用,但值得感谢的是Peter Upfold- http: //peter.upfold.org.uk/

  • 安装Virtualbox并将VM设置为接受RDP会话。
  • 下载VBoxVmService并将其安装到C:\ vms。只是Google VBoxVmService提供了下载链接(对不起,代表不足以发布2个以上链接)。
  • 在C:\ vms下编辑VBoxVmService的ini文件:

[设定]

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将在启动时启动。


1
您可以总结一下答案中的链接,以防其失效吗?
jonsca

根据要求编辑帖子。
RooiWillie

在VirtualBox的4.2.x版本上可以使用吗?
Archimedes Trajano 2013年

这些说明可能适用于某些较旧的版本,当前版本的VBoxVmService(4.1)更易于设置,并会指导您完成整个过程。
Melebius

2

只是提供此作为另一种选择:

使用内置的Windows命令'sc'创建服务。将其与“ vboxheadless”结合使用将使您到达想要的位置。

未经过vboxheadless专门测试,但是我确实创建了运行calc.exe的测试服务。您应该这样做:

sc create servicenamehere start= auto binPath= "C:\path\to\vboxheadless.exe --startvm name"

有关更多信息,请参考sc的文档。注意:等号后的空格是故意的。


这将正确启动服务,但在服务停止时将使VM崩溃-VBoxHeadless无法正确解释服务停止控件,因此Windows将等待直到超时,然后强行终止该进程,这不理想。请参阅其他有关包装脚本的答案,以防止发生这种情况。
亚伦·米勒

感谢您的评论。希望将其作为错误修复/功能请求提交给开发人员。
亚伦·科普利2012年

1

如果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。我自己不需要这样做,所以我不确定它是否可以工作,但是我不知道为什么不行。(如果您尝试过,我很乐意对此答案发表评论,让我知道它为您带来的效果。谢谢!)

希望这可以帮助!


您的脚本更简单,但是需要Perl并将其硬编码为vboxd脚本接受为参数的几个属性。根据virtualbox.org/manual/ch07.html的说法,如果VM设置为使用另一RDP服务器正在使用的默认端口,则VBoxHeadless将不接受VRDE端口,从而不会运行VM(它会无限期地阻塞)。vboxd-install这很有用,因为它可以方便地隐藏cygrunsrv的参数详细信息。不过,我同意,这acpipowerbutton是比更好的“停止”选择savestate
德里克·马哈尔

@DerekMahar,我想不管它的价值。由于它不适用于XP以上的任何版本,因此我怀疑无论如何都存在很多问题。¯\ _(ツ)_ /¯感谢您的反馈!
亚伦·米勒

亚伦·米勒(Aaron Miller),您是说您的脚本或vboxd在Windows XP以上的Windows上不起作用?我想您的意思是您的脚本,因为我确实将vboxd运用于带有VirtualBox 5.1.6的Windows 10。
德里克·马哈

@DerekMahar我的意思是我的脚本,不是vboxd。
亚伦·米勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.