題 如何在Windows XP上將VirtualBox計算機作為服務運行?


我在Windows XP主機上安裝了帶有Windows XP的VirtualBox機器。

我如何啟動VirtualBox作為服務,因此我可以獲得一個虛擬機,我不必啟動VirtualBox來訪問我的虛擬機(通過網絡中的VNC)?

我發現VirtualBox Manage可能是最佳選擇,但由於我是初學者,我不知道從哪裡開始。

有任何想法嗎?


12
2018-01-05 19:08


起源




答案:


創建快捷方式 C:\Program Files\innotek VirtualBox\VBoxManage.exe

引號後輸入: startvm <your virtual machine name>

例:

“C:\Program Files\innotek VirtualBox\VBoxManage.exe” startvm XP

將快捷方式複制/移動到啟動文件夾。

p.s。:如果要在系統完全啟動之前延遲虛擬機,可以在XP中執行此操作 啟動Delayer


0
2018-01-05 19:29



它似乎工作正常,無論如何還要“隱藏”虛擬機的窗口,所以它運行更像是一個Windows服務? - Jhonny D. Cano -Leftware-
運行VBox作為服務不會隱藏窗口。您可以使用AWM自動將其最小化到系統托盤: eusing.com/WindowManager/WindowManager.htm
checkout“VBoxHeadless”用於在沒有UI的情況下啟動VM。如果要查看VM的屏幕,則需要使用RDP。 - Mark Porter
這不是服務。這只在您登錄時運行VBox - 而不是在機器開機時運行。 VBoxHeadless是作為服務運行的方式。請參閱下面的答案(根據Aaron Copley的評論,我即將改進)。 - John Hart
答案與作為服務運行無關。用戶登錄後發生啟動,完全不同於服務行為。 - Felice Pollano


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

這個解決方案對我很有用;希望你有類似的運氣。


9
2018-01-03 22:04



+1“不是服務”... -1用於鏈接到解決方案而不是將其包含在答案中。投票無效。 :)考慮修改以包含解決方案,因為鏈接腐爛不利於此答案的壽命。 - Aaron Copley


看起來最簡單的答案就是 VBoxVMService。我還沒有嘗試過,我會盡量記得來這裡並在我做的時候更新答案。


8
2017-10-26 19:30



但它不適用於4.2.x. - Archimedes Trajano
@ArchimedesTrajano我用VirtualBox 4.3.6嘗試了當前版本(4.1),運行良好。該項目的頁面聲稱它是 “從頭開始重寫”。 - Melebius
是的,我昨晚測試了它,它的確有效!只記得重新啟動。 - Archimedes Trajano


同意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中。只需谷歌VBoxVmService下載鏈接(抱歉,沒有足夠的代表發布2個以上的鏈接)。
  • 在C:\ vms下編輯VBoxVmService的ini文件:

[設置]

服務名稱= VBoxVmService

VBOX_USER_HOME = C:\用戶\ Administrator.VirtualBox

RunAsUser = \管理員

的userPassword = enteryourpasswordhere

RunWebService =無

PauseShutdown = 5000

[VM0]   VmName = VirtualBox中vm的名稱

ShutdownMethod = saveState和

自動啟動= YES

  • 將VBOX_USER_HOME替換為正確用戶主目錄中的.VirtualBox文件夾,以及RunAsUser和UserPassword指令,並在VmName中的VirtualBox應用程序中設置目標虛擬機的名稱。您還可以在[Vm0]之後添加其他[Vmx]部分,以便在計算機啟動時啟動其他虛擬機。

  • 如果對配置感到滿意,請從啟用管理員的命令提示符運行以下命令來安裝該服務。安裝服務後,您可以從INI文件中刪除用戶密碼,因為它保存在服務配置中:

C:\ vms \ VmServiceControl.exe -i

  • 現在,您必須在嘗試首次啟動服務之前重新啟動計算機,否則將無法找到VM。

  • 重新啟動後,服務應該啟動(受“自動(延遲啟動)”延遲),並且您的VM將在啟動時啟動。


4
2017-08-13 10:21



你可以總結一下你答案中的鏈接嗎? - jonsca
根據要求編輯帖子。 - RooiWillie
這是否適用於VirtualBox的4.2.x版本? - Archimedes Trajano
這些說明可能適用於某些舊版本,當前版本的VBoxVmService(4.1)更易於設置,它將指導您完成整個過程。 - Melebius


只是提供這個作為另一種選擇:

使用內置的Windows命令'sc'來創建服務。將其與'vboxheadless'相結合,將帶您到達您想去的地方。

沒有經過vboxhead特別測試,但我確實創建了一個運行calc.exe的測試服務。你應該做這樣的事情:

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

有關更多信息,請參閱sc的文檔。注意:等號後的那些空格是故意的。


2
2018-01-03 22:17



這將正確啟動服務,但是當服務停止時將使VM崩潰 - VBoxHeadless無法正確解釋服務停止控制,因此Windows將等到超時然後強制終止進程,這不太理想。請參閱包裝器腳本的其他答案以防止發生這種情況。 - Aaron Miller
感謝您的評論。希望這是作為錯誤修復/功能請求提交給開發人員的。 - Aaron Copley


如果vboxd腳本給你的麻煩和他們一樣多,你可能想嘗試一下;它是一個相當簡單的解決方案,在Perl中實現,它提供相同的功能。具體來說,VM啟動系統(假設服務設置為自動啟動,這是默認設置),並在服務停止時干淨地停機。

除了根據我的經驗處理起來相當簡單之外,與vboxd解決方案的主要區別在於,此腳本不會將VRDE端口設置傳遞給VBoxHeadless,並且VM關閉通過“acpipowerbutton”而不是“savestate”來處理。

如果這不符合您的目的,則很容易改變;在第一種情況下,將'-e“TCP / Ports = [,port ...]”'添加到VBoxHeadless命令行字符串($ cmd),在第二種情況下,只需將“acpipowerbutton”更改為“savestate”in 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;它似乎處於“已關閉電源”狀態,您將無法進入其設置。 (嘗試在作為服務運行時啟動VM 不建議  - 我不知道會發生什麼,但充其量只是一個無操作,最糟糕的是它會阻塞你的VM。)如果你需要更改VM的設置或訪問控制台,請停止服務首先(等待VBoxHeadless.exe退出),然後像往常一樣在VirtualBox控制台中配置它/啟動它。

您可以通過安裝第二個交互式服務來運行VirtualBox控制台來解決此問題;因為這也會在SYSTEM帳戶下運行控制台,所以它很可能能夠查看和管理正在運行的VM。我自己沒有必要這樣做,所以我不確定它會起作用,但我不明白為什麼它不會。 (如果你試試,我會很感激對這個答案的評論,讓我知道它是如何為你效果的。謝謝!)

希望這可以幫助!


1
2017-10-01 15:29



您的腳本更簡單,但需要Perl和硬編碼vbox腳本接受的幾個屬性作為參數。根據 virtualbox.org/manual/ch07.html如果VM被設置為使用另一個RDP服務器正在使用的默認端口,則不接受VRDE端口,VBoxHeadless將不會運行VM(它只是無限期地阻塞)。 vboxd-install 很有幫助,因為它方便地隱藏了cygrunsrv的參數細節。不過,我同意這一點 acpipowerbutton 是比一個更好的“停止”選項 savestate。 - Derek Mahar
@DerekMahar我認為,不管它有什麼價值,都要接受它。由於它不適用於任何比XP更新的東西,我懷疑在任何情況下都是如此。 ¯\ _(ツ)_ /¯感謝您的反饋! - Aaron Miller
Aaron Miller,你的意思是你的腳本或vboxd不能在任何比XP更新的Windows上運行嗎?我認為你的意思是你的腳本,因為我確實讓vboxd在使用VirtualBox 5.1.6的Windows 10上工作。 - Derek Mahar
@DerekMahar我的意思是我的腳本,而不是vboxd。 - Aaron Miller