init windowshost
This commit is contained in:
4
computer_use_demo/windowshost/.gitignore
vendored
Normal file
4
computer_use_demo/windowshost/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
vm/win11iso/custom.iso
|
||||
vm/win11storage
|
||||
vm/win11setup/setupscripts/firstboot_log.txt
|
||||
vm/win11setup/setupscripts/server/server.log
|
||||
48
computer_use_demo/windowshost/Dockerfile
Normal file
48
computer_use_demo/windowshost/Dockerfile
Normal file
@@ -0,0 +1,48 @@
|
||||
ARG VERSION_ARG="latest"
|
||||
FROM scratch AS build-amd64
|
||||
|
||||
COPY --from=qemux/qemu-docker:6.08 / /
|
||||
|
||||
ARG DEBCONF_NOWARNINGS="yes"
|
||||
ARG DEBIAN_FRONTEND="noninteractive"
|
||||
ARG DEBCONF_NONINTERACTIVE_SEEN="true"
|
||||
|
||||
RUN set -eu && \
|
||||
apt-get update && \
|
||||
apt-get --no-install-recommends -y install \
|
||||
bc \
|
||||
jq \
|
||||
curl \
|
||||
7zip \
|
||||
wsdd \
|
||||
samba \
|
||||
xz-utils \
|
||||
wimtools \
|
||||
dos2unix \
|
||||
cabextract \
|
||||
genisoimage \
|
||||
libxml2-utils \
|
||||
libarchive-tools && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
COPY --chmod=755 ./vm/buildcontainer /run/
|
||||
RUN dos2unix /run/*
|
||||
|
||||
COPY --chmod=755 ./vm/win11def /run/assets
|
||||
RUN dos2unix /run/assets/*
|
||||
|
||||
ADD --chmod=755 https://raw.githubusercontent.com/christgau/wsdd/v0.8/src/wsdd.py /usr/sbin/wsdd
|
||||
ADD --chmod=664 https://github.com/qemus/virtiso-whql/releases/download/v1.9.43-0/virtio-win-1.9.43.tar.xz /drivers.txz
|
||||
|
||||
FROM dockurr/windows-arm:${VERSION_ARG} AS build-arm64
|
||||
FROM build-${TARGETARCH}
|
||||
|
||||
ARG VERSION_ARG="0.00"
|
||||
RUN echo "$VERSION_ARG" > /run/version
|
||||
|
||||
EXPOSE 8006 3389
|
||||
|
||||
ENV VERSION="win11e"
|
||||
|
||||
ENTRYPOINT ["/usr/bin/tini", "-s", "/run/entry.sh"]
|
||||
23
computer_use_demo/windowshost/compose.yml
Normal file
23
computer_use_demo/windowshost/compose.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
services:
|
||||
windows:
|
||||
image: windows-local
|
||||
container_name: omni-windows
|
||||
privileged: true
|
||||
environment:
|
||||
RAM_SIZE: "8G"
|
||||
CPU_CORES: "4"
|
||||
DISK_SIZE: "20G"
|
||||
devices:
|
||||
- /dev/kvm
|
||||
- /dev/net/tun
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
ports:
|
||||
- 8006:8006 # Web Viewer access
|
||||
- 5000:5000 # Computer control server
|
||||
volumes:
|
||||
- ./vm/win11iso/custom.iso:/custom.iso
|
||||
- ./vm/win11setup/firstboot:/oem
|
||||
- ./vm/win11setup/setupscripts:/data
|
||||
- ./vm/win11storage:/storage
|
||||
|
||||
70
computer_use_demo/windowshost/scripts/manage_vm.ps1
Normal file
70
computer_use_demo/windowshost/scripts/manage_vm.ps1
Normal file
@@ -0,0 +1,70 @@
|
||||
function Create-VM {
|
||||
if (-not (docker images windows-local -q)) {
|
||||
Write-Host "Image not found locally. Building..."
|
||||
docker build -t windows-local ..
|
||||
} else {
|
||||
Write-Host "Image found locally. Skipping build."
|
||||
}
|
||||
|
||||
docker compose -f ../compose.yml up -d
|
||||
|
||||
while ($true) {
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri "http://localhost:5000/probe" -Method GET -UseBasicParsing
|
||||
if ($response.StatusCode -eq 200) {
|
||||
break
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Waiting for a response from the computer control server. When first building the VM storage folder this can take a while..."
|
||||
Start-Sleep -Seconds 5
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "VM + server is up and running!"
|
||||
}
|
||||
|
||||
function Start-LocalVM {
|
||||
Write-Host "Starting VM..."
|
||||
docker compose -f ../compose.yml start
|
||||
while ($true) {
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri "http://localhost:5000/probe" -Method GET -UseBasicParsing
|
||||
if ($response.StatusCode -eq 200) {
|
||||
break
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Waiting for a response from the computer control server"
|
||||
Start-Sleep -Seconds 5
|
||||
}
|
||||
}
|
||||
Write-Host "VM started"
|
||||
}
|
||||
|
||||
function Stop-LocalVM {
|
||||
Write-Host "Stopping VM..."
|
||||
docker compose -f ../compose.yml stop
|
||||
Write-Host "VM stopped"
|
||||
}
|
||||
|
||||
function Remove-VM {
|
||||
Write-Host "Removing VM and associated containers..."
|
||||
docker compose -f ../compose.yml down
|
||||
Write-Host "VM removed"
|
||||
}
|
||||
|
||||
if (-not $args[0]) {
|
||||
Write-Host "Usage: $($MyInvocation.MyCommand.Name) [create|start|stop|delete]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
switch ($args[0]) {
|
||||
"create" { Create-VM }
|
||||
"start" { Start-LocalVM }
|
||||
"stop" { Stop-LocalVM }
|
||||
"delete" { Remove-VM }
|
||||
default {
|
||||
Write-Host "Invalid option: $($args[0])"
|
||||
Write-Host "Usage: $($MyInvocation.MyCommand.Name) [create|start|stop|delete]"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
77
computer_use_demo/windowshost/scripts/manage_vm.sh
Executable file
77
computer_use_demo/windowshost/scripts/manage_vm.sh
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/bin/bash
|
||||
|
||||
create_vm() {
|
||||
if ! docker images windows-local -q | grep -q .; then
|
||||
echo "Image not found locally. Building..."
|
||||
docker build -t windows-local ..
|
||||
else
|
||||
echo "Image found locally. Skipping build."
|
||||
fi
|
||||
|
||||
docker compose -f ../compose.yml up -d
|
||||
|
||||
# Wait for the VM to start up
|
||||
while true; do
|
||||
response=$(curl --write-out '%{http_code}' --silent --output /dev/null localhost:5000/probe)
|
||||
if [ $response -eq 200 ]; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting for a response from the computer control server. When first building the VM storage folder this can take a while..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "VM + server is up and running!"
|
||||
}
|
||||
|
||||
start_vm() {
|
||||
echo "Starting VM..."
|
||||
docker compose -f ../compose.yml start
|
||||
while true; do
|
||||
response=$(curl --write-out '%{http_code}' --silent --output /dev/null localhost:5000/probe)
|
||||
if [ $response -eq 200 ]; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting for a response from the computer control server"
|
||||
sleep 5
|
||||
done
|
||||
echo "VM started"
|
||||
}
|
||||
|
||||
stop_vm() {
|
||||
echo "Stopping VM..."
|
||||
docker compose -f ../compose.yml stop
|
||||
echo "VM stopped"
|
||||
}
|
||||
|
||||
delete_vm() {
|
||||
echo "Removing VM and associated containers..."
|
||||
docker compose -f ../compose.yml down
|
||||
echo "VM removed"
|
||||
}
|
||||
|
||||
# Check if control parameter is provided
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 [create|start|stop|delete]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute the appropriate function based on the control parameter
|
||||
case "$1" in
|
||||
"create")
|
||||
create_vm
|
||||
;;
|
||||
"start")
|
||||
start_vm
|
||||
;;
|
||||
"stop")
|
||||
stop_vm
|
||||
;;
|
||||
"delete")
|
||||
delete_vm
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option: $1"
|
||||
echo "Usage: $0 [create|start|stop|delete]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
410
computer_use_demo/windowshost/vm/buildcontainer/define.sh
Normal file
410
computer_use_demo/windowshost/vm/buildcontainer/define.sh
Normal file
@@ -0,0 +1,410 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
: "${WIDTH:=""}"
|
||||
: "${HEIGHT:=""}"
|
||||
: "${VERIFY:=""}"
|
||||
: "${REGION:=""}"
|
||||
: "${MANUAL:=""}"
|
||||
: "${REMOVE:=""}"
|
||||
: "${VERSION:=""}"
|
||||
: "${DETECTED:=""}"
|
||||
: "${KEYBOARD:=""}"
|
||||
: "${LANGUAGE:=""}"
|
||||
: "${USERNAME:=""}"
|
||||
: "${PASSWORD:=""}"
|
||||
|
||||
MIRRORS=4
|
||||
PLATFORM="x64"
|
||||
|
||||
parseVersion() {
|
||||
|
||||
if [[ "${VERSION}" == \"*\" || "${VERSION}" == \'*\' ]]; then
|
||||
VERSION="${VERSION:1:-1}"
|
||||
fi
|
||||
|
||||
[ -z "$VERSION" ] && VERSION="win11"
|
||||
|
||||
case "${VERSION,,}" in
|
||||
"11" | "11p" | "win11" | "pro11" | "win11p" | "windows11" | "windows 11" )
|
||||
VERSION="win11x64"
|
||||
;;
|
||||
"11e" | "win11e" | "windows11e" | "windows 11e" | "win11x64-enterprise-eval" )
|
||||
VERSION="win11x64-enterprise-eval"
|
||||
;;
|
||||
esac
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
getLanguage() {
|
||||
|
||||
local id="$1"
|
||||
local ret="$2"
|
||||
local lang=""
|
||||
local desc=""
|
||||
local culture=""
|
||||
|
||||
case "${id,,}" in
|
||||
"ar" | "ar-"* )
|
||||
lang="Arabic"
|
||||
desc="$lang"
|
||||
culture="ar-SA" ;;
|
||||
"bg" | "bg-"* )
|
||||
lang="Bulgarian"
|
||||
desc="$lang"
|
||||
culture="bg-BG" ;;
|
||||
"cs" | "cs-"* | "cz" | "cz-"* )
|
||||
lang="Czech"
|
||||
desc="$lang"
|
||||
culture="cs-CZ" ;;
|
||||
"da" | "da-"* | "dk" | "dk-"* )
|
||||
lang="Danish"
|
||||
desc="$lang"
|
||||
culture="da-DK" ;;
|
||||
"de" | "de-"* )
|
||||
lang="German"
|
||||
desc="$lang"
|
||||
culture="de-DE" ;;
|
||||
"el" | "el-"* | "gr" | "gr-"* )
|
||||
lang="Greek"
|
||||
desc="$lang"
|
||||
culture="el-GR" ;;
|
||||
"gb" | "en-gb" )
|
||||
lang="English International"
|
||||
desc="English"
|
||||
culture="en-GB" ;;
|
||||
"en" | "en-"* )
|
||||
lang="English"
|
||||
desc="English"
|
||||
culture="en-US" ;;
|
||||
"mx" | "es-mx" )
|
||||
lang="Spanish (Mexico)"
|
||||
desc="Spanish"
|
||||
culture="es-MX" ;;
|
||||
"es" | "es-"* )
|
||||
lang="Spanish"
|
||||
desc="$lang"
|
||||
culture="es-ES" ;;
|
||||
"et" | "et-"* )
|
||||
lang="Estonian"
|
||||
desc="$lang"
|
||||
culture="et-EE" ;;
|
||||
"fi" | "fi-"* )
|
||||
lang="Finnish"
|
||||
desc="$lang"
|
||||
culture="fi-FI" ;;
|
||||
"ca" | "fr-ca" )
|
||||
lang="French Canadian"
|
||||
desc="French"
|
||||
culture="fr-CA" ;;
|
||||
"fr" | "fr-"* )
|
||||
lang="French"
|
||||
desc="$lang"
|
||||
culture="fr-FR" ;;
|
||||
"he" | "he-"* | "il" | "il-"* )
|
||||
lang="Hebrew"
|
||||
desc="$lang"
|
||||
culture="he-IL" ;;
|
||||
"hr" | "hr-"* | "cr" | "cr-"* )
|
||||
lang="Croatian"
|
||||
desc="$lang"
|
||||
culture="hr-HR" ;;
|
||||
"hu" | "hu-"* )
|
||||
lang="Hungarian"
|
||||
desc="$lang"
|
||||
culture="hu-HU" ;;
|
||||
"it" | "it-"* )
|
||||
lang="Italian"
|
||||
desc="$lang"
|
||||
culture="it-IT" ;;
|
||||
"ja" | "ja-"* | "jp" | "jp-"* )
|
||||
lang="Japanese"
|
||||
desc="$lang"
|
||||
culture="ja-JP" ;;
|
||||
"ko" | "ko-"* | "kr" | "kr-"* )
|
||||
lang="Korean"
|
||||
desc="$lang"
|
||||
culture="ko-KR" ;;
|
||||
"lt" | "lt-"* )
|
||||
lang="Lithuanian"
|
||||
desc="$lang"
|
||||
culture="lv-LV" ;;
|
||||
"lv" | "lv-"* )
|
||||
lang="Latvian"
|
||||
desc="$lang"
|
||||
culture="lt-LT" ;;
|
||||
"nb" | "nb-"* |"nn" | "nn-"* | "no" | "no-"* )
|
||||
lang="Norwegian"
|
||||
desc="$lang"
|
||||
culture="nb-NO" ;;
|
||||
"nl" | "nl-"* )
|
||||
lang="Dutch"
|
||||
desc="$lang"
|
||||
culture="nl-NL" ;;
|
||||
"pl" | "pl-"* )
|
||||
lang="Polish"
|
||||
desc="$lang"
|
||||
culture="pl-PL" ;;
|
||||
"br" | "pt-br" )
|
||||
lang="Brazilian Portuguese"
|
||||
desc="Portuguese"
|
||||
culture="pt-BR" ;;
|
||||
"pt" | "pt-"* )
|
||||
lang="Portuguese"
|
||||
desc="$lang"
|
||||
culture="pt-BR" ;;
|
||||
"ro" | "ro-"* )
|
||||
lang="Romanian"
|
||||
desc="$lang"
|
||||
culture="ro-RO" ;;
|
||||
"ru" | "ru-"* )
|
||||
lang="Russian"
|
||||
desc="$lang"
|
||||
culture="ru-RU" ;;
|
||||
"sk" | "sk-"* )
|
||||
lang="Slovak"
|
||||
desc="$lang"
|
||||
culture="sk-SK" ;;
|
||||
"sl" | "sl-"* | "si" | "si-"* )
|
||||
lang="Slovenian"
|
||||
desc="$lang"
|
||||
culture="sl-SI" ;;
|
||||
"sr" | "sr-"* )
|
||||
lang="Serbian Latin"
|
||||
desc="Serbian"
|
||||
culture="sr-Latn-RS" ;;
|
||||
"sv" | "sv-"* | "se" | "se-"* )
|
||||
lang="Swedish"
|
||||
desc="$lang"
|
||||
culture="sv-SE" ;;
|
||||
"th" | "th-"* )
|
||||
lang="Thai"
|
||||
desc="$lang"
|
||||
culture="th-TH" ;;
|
||||
"tr" | "tr-"* )
|
||||
lang="Turkish"
|
||||
desc="$lang"
|
||||
culture="tr-TR" ;;
|
||||
"ua" | "ua-"* | "uk" | "uk-"* )
|
||||
lang="Ukrainian"
|
||||
desc="$lang"
|
||||
culture="uk-UA" ;;
|
||||
"hk" | "zh-hk" | "cn-hk" )
|
||||
lang="Chinese (Traditional)"
|
||||
desc="Chinese HK"
|
||||
culture="zh-TW" ;;
|
||||
"tw" | "zh-tw" | "cn-tw" )
|
||||
lang="Chinese (Traditional)"
|
||||
desc="Chinese TW"
|
||||
culture="zh-TW" ;;
|
||||
"zh" | "zh-"* | "cn" | "cn-"* )
|
||||
lang="Chinese (Simplified)"
|
||||
desc="Chinese"
|
||||
culture="zh-CN" ;;
|
||||
esac
|
||||
|
||||
case "${ret,,}" in
|
||||
"desc" ) echo "$desc" ;;
|
||||
"name" ) echo "$lang" ;;
|
||||
"culture" ) echo "$culture" ;;
|
||||
*) echo "$desc";;
|
||||
esac
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
parseLanguage() {
|
||||
|
||||
REGION="${REGION//_/-/}"
|
||||
KEYBOARD="${KEYBOARD//_/-/}"
|
||||
LANGUAGE="${LANGUAGE//_/-/}"
|
||||
|
||||
[ -z "$LANGUAGE" ] && LANGUAGE="en"
|
||||
|
||||
case "${LANGUAGE,,}" in
|
||||
"arabic" | "arab" ) LANGUAGE="ar" ;;
|
||||
"bulgarian" | "bu" ) LANGUAGE="bg" ;;
|
||||
"chinese" | "cn" ) LANGUAGE="zh" ;;
|
||||
"croatian" | "cr" | "hrvatski" ) LANGUAGE="hr" ;;
|
||||
"czech" | "cz" | "cesky" ) LANGUAGE="cs" ;;
|
||||
"danish" | "dk" | "danske" ) LANGUAGE="da" ;;
|
||||
"dutch" | "nederlands" ) LANGUAGE="nl" ;;
|
||||
"english" | "gb" | "british" ) LANGUAGE="en" ;;
|
||||
"estonian" | "eesti" ) LANGUAGE="et" ;;
|
||||
"finnish" | "suomi" ) LANGUAGE="fi" ;;
|
||||
"french" | "français" | "francais" ) LANGUAGE="fr" ;;
|
||||
"german" | "deutsch" ) LANGUAGE="de" ;;
|
||||
"greek" | "gr" ) LANGUAGE="el" ;;
|
||||
"hebrew" | "il" ) LANGUAGE="he" ;;
|
||||
"hungarian" | "magyar" ) LANGUAGE="hu" ;;
|
||||
"italian" | "italiano" ) LANGUAGE="it" ;;
|
||||
"japanese" | "jp" ) LANGUAGE="ja" ;;
|
||||
"korean" | "kr" ) LANGUAGE="ko" ;;
|
||||
"latvian" | "latvijas" ) LANGUAGE="lv" ;;
|
||||
"lithuanian" | "lietuvos" ) LANGUAGE="lt" ;;
|
||||
"norwegian" | "no" | "nb" | "norsk" ) LANGUAGE="nn" ;;
|
||||
"polish" | "polski" ) LANGUAGE="pl" ;;
|
||||
"portuguese" | "pt" | "br" ) LANGUAGE="pt-br" ;;
|
||||
"português" | "portugues" ) LANGUAGE="pt-br" ;;
|
||||
"romanian" | "română" | "romana" ) LANGUAGE="ro" ;;
|
||||
"russian" | "ruski" ) LANGUAGE="ru" ;;
|
||||
"serbian" | "serbian latin" ) LANGUAGE="sr" ;;
|
||||
"slovak" | "slovenský" | "slovensky" ) LANGUAGE="sk" ;;
|
||||
"slovenian" | "si" | "slovenski" ) LANGUAGE="sl" ;;
|
||||
"spanish" | "espanol" | "español" ) LANGUAGE="es" ;;
|
||||
"swedish" | "se" | "svenska" ) LANGUAGE="sv" ;;
|
||||
"turkish" | "türk" | "turk" ) LANGUAGE="tr" ;;
|
||||
"thai" ) LANGUAGE="th" ;;
|
||||
"ukrainian" | "ua" ) LANGUAGE="uk" ;;
|
||||
esac
|
||||
|
||||
local culture
|
||||
culture=$(getLanguage "$LANGUAGE" "culture")
|
||||
[ -n "$culture" ] && return 0
|
||||
|
||||
error "Invalid LANGUAGE specified, value \"$LANGUAGE\" is not recognized!"
|
||||
return 1
|
||||
}
|
||||
|
||||
printVersion() {
|
||||
|
||||
local id="$1"
|
||||
local desc="$2"
|
||||
|
||||
case "${id,,}" in
|
||||
"win11"* ) desc="Windows 11" ;;
|
||||
esac
|
||||
|
||||
if [ -z "$desc" ]; then
|
||||
desc="Windows"
|
||||
[[ "${PLATFORM,,}" != "x64" ]] && desc+=" for ${PLATFORM}"
|
||||
fi
|
||||
|
||||
echo "$desc"
|
||||
return 0
|
||||
}
|
||||
|
||||
printEdition() {
|
||||
|
||||
local id="$1"
|
||||
local desc="$2"
|
||||
local result=""
|
||||
local edition=""
|
||||
|
||||
result=$(printVersion "$id" "x")
|
||||
[[ "$result" == "x" ]] && echo "$desc" && return 0
|
||||
|
||||
case "${id,,}" in
|
||||
*"-enterprise" )
|
||||
edition="Enterprise"
|
||||
;;
|
||||
*"-enterprise-eval" )
|
||||
edition="Enterprise (Evaluation)"
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "$edition" ] && result+=" $edition"
|
||||
|
||||
echo "$result"
|
||||
return 0
|
||||
}
|
||||
|
||||
fromName() {
|
||||
|
||||
local id=""
|
||||
local name="$1"
|
||||
local arch="$2"
|
||||
|
||||
local add=""
|
||||
[[ "$arch" != "x64" ]] && add="$arch"
|
||||
|
||||
case "${name,,}" in
|
||||
*"windows 11"* ) id="win11${arch}" ;;
|
||||
esac
|
||||
|
||||
echo "$id"
|
||||
return 0
|
||||
}
|
||||
|
||||
getVersion() {
|
||||
|
||||
local id
|
||||
local name="$1"
|
||||
local arch="$2"
|
||||
|
||||
id=$(fromName "$name" "$arch")
|
||||
|
||||
case "${id,,}" in
|
||||
"win11"* )
|
||||
case "${name,,}" in
|
||||
*" enterprise evaluation"* ) id="$id-enterprise-eval" ;;
|
||||
*" enterprise"* ) id="$id-enterprise" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$id"
|
||||
return 0
|
||||
}
|
||||
|
||||
addFolder() {
|
||||
|
||||
local src="$1"
|
||||
local folder="/oem"
|
||||
|
||||
[ ! -d "$folder" ] && folder="/OEM"
|
||||
[ ! -d "$folder" ] && folder="$STORAGE/oem"
|
||||
[ ! -d "$folder" ] && folder="$STORAGE/OEM"
|
||||
[ ! -d "$folder" ] && return 0
|
||||
|
||||
local msg="Adding OEM folder to image..."
|
||||
info "$msg" && html "$msg"
|
||||
|
||||
local dest="$src/\$OEM\$/\$1/OEM"
|
||||
mkdir -p "$dest" || return 1
|
||||
cp -Lr "$folder/." "$dest" || return 1
|
||||
|
||||
local file
|
||||
file=$(find "$dest" -maxdepth 1 -type f -iname install.bat | head -n 1)
|
||||
[ -f "$file" ] && unix2dos -q "$file"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# migrateFiles() {
|
||||
|
||||
# local base="$1"
|
||||
# local version="$2"
|
||||
# local file=""
|
||||
|
||||
# [ -f "$base" ] && return 0
|
||||
|
||||
# [[ "${version,,}" == "tiny10" ]] && file="tiny10_x64_23h2.iso"
|
||||
# [[ "${version,,}" == "tiny11" ]] && file="tiny11_2311_x64.iso"
|
||||
# [[ "${version,,}" == "core11" ]] && file="tiny11_core_x64_beta_1.iso"
|
||||
# [[ "${version,,}" == "winxpx86" ]] && file="en_windows_xp_professional_with_service_pack_3_x86_cd_x14-80428.iso"
|
||||
# [[ "${version,,}" == "winvistax64" ]] && file="en_windows_vista_sp2_x64_dvd_342267.iso"
|
||||
# [[ "${version,,}" == "win7x64" ]] && file="en_windows_7_enterprise_with_sp1_x64_dvd_u_677651.iso"
|
||||
|
||||
# [ ! -f "$STORAGE/$file" ] && return 0
|
||||
# mv -f "$STORAGE/$file" "$base" || return 1
|
||||
|
||||
# return 0
|
||||
# }
|
||||
|
||||
migrateFiles() {
|
||||
|
||||
local base="$1"
|
||||
local version="$2"
|
||||
local file=""
|
||||
|
||||
[ -f "$base" ] && return 0
|
||||
|
||||
[ ! -f "$STORAGE/$file" ] && return 0
|
||||
mv -f "$STORAGE/$file" "$base" || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
return 0
|
||||
38
computer_use_demo/windowshost/vm/buildcontainer/entry.sh
Normal file
38
computer_use_demo/windowshost/vm/buildcontainer/entry.sh
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
: "${BOOT_MODE:="windows"}"
|
||||
|
||||
APP="OmniParser Windows"
|
||||
SUPPORT="https://github.com/microsoft/OmniParser"
|
||||
|
||||
cd /run
|
||||
|
||||
. reset.sh # Initialize system
|
||||
. define.sh # Define versions
|
||||
. install.sh # Run installation
|
||||
. disk.sh # Initialize disks
|
||||
. display.sh # Initialize graphics
|
||||
. network.sh # Initialize network
|
||||
. samba.sh # Configure samba
|
||||
. boot.sh # Configure boot
|
||||
. proc.sh # Initialize processor
|
||||
. power.sh # Configure shutdown
|
||||
. config.sh # Configure arguments
|
||||
|
||||
trap - ERR
|
||||
|
||||
version=$(qemu-system-x86_64 --version | head -n 1 | cut -d '(' -f 1 | awk '{ print $NF }')
|
||||
info "Booting ${APP}${BOOT_DESC} using QEMU v$version..."
|
||||
|
||||
{ qemu-system-x86_64 ${ARGS:+ $ARGS} >"$QEMU_OUT" 2>"$QEMU_LOG"; rc=$?; } || :
|
||||
(( rc != 0 )) && error "$(<"$QEMU_LOG")" && exit 15
|
||||
|
||||
terminal
|
||||
( sleep 30; boot ) &
|
||||
tail -fn +0 "$QEMU_LOG" 2>/dev/null &
|
||||
cat "$QEMU_TERM" 2> /dev/null | tee "$QEMU_PTY" &
|
||||
wait $! || :
|
||||
|
||||
sleep 1 & wait $!
|
||||
[ ! -f "$QEMU_END" ] && finish 0
|
||||
1024
computer_use_demo/windowshost/vm/buildcontainer/install.sh
Normal file
1024
computer_use_demo/windowshost/vm/buildcontainer/install.sh
Normal file
File diff suppressed because it is too large
Load Diff
223
computer_use_demo/windowshost/vm/buildcontainer/power.sh
Normal file
223
computer_use_demo/windowshost/vm/buildcontainer/power.sh
Normal file
@@ -0,0 +1,223 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
# Configure QEMU for graceful shutdown
|
||||
|
||||
QEMU_TERM=""
|
||||
QEMU_PORT=7100
|
||||
QEMU_TIMEOUT=110
|
||||
QEMU_DIR="/run/shm"
|
||||
QEMU_PID="$QEMU_DIR/qemu.pid"
|
||||
QEMU_PTY="$QEMU_DIR/qemu.pty"
|
||||
QEMU_LOG="$QEMU_DIR/qemu.log"
|
||||
QEMU_OUT="$QEMU_DIR/qemu.out"
|
||||
QEMU_END="$QEMU_DIR/qemu.end"
|
||||
|
||||
rm -f "$QEMU_DIR/qemu.*"
|
||||
touch "$QEMU_LOG"
|
||||
|
||||
_trap() {
|
||||
func="$1" ; shift
|
||||
for sig ; do
|
||||
trap "$func $sig" "$sig"
|
||||
done
|
||||
}
|
||||
|
||||
boot() {
|
||||
|
||||
[ -f "$QEMU_END" ] && return 0
|
||||
|
||||
if [ -s "$QEMU_PTY" ]; then
|
||||
if [ "$(stat -c%s "$QEMU_PTY")" -gt 7 ]; then
|
||||
local fail=""
|
||||
if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
|
||||
grep -Fq "No bootable device." "$QEMU_PTY" && fail="y"
|
||||
grep -Fq "BOOTMGR is missing" "$QEMU_PTY" && fail="y"
|
||||
fi
|
||||
if [ -z "$fail" ]; then
|
||||
info "Windows has started successfully. You can directly view the VM at http://localhost:8006/vnc.html?view_only=1&autoconnect=1&resize=scale. Wait until setup is complete before interacting manually."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
error "Timeout while waiting for QEMU to boot the machine!"
|
||||
|
||||
local pid
|
||||
pid=$(<"$QEMU_PID")
|
||||
{ kill -15 "$pid" || true; } 2>/dev/null
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
ready() {
|
||||
|
||||
[ -f "$STORAGE/windows.boot" ] && return 0
|
||||
[ ! -s "$QEMU_PTY" ] && return 1
|
||||
|
||||
if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
|
||||
local last
|
||||
local bios="Booting from Hard"
|
||||
last=$(grep "^Booting.*" "$QEMU_PTY" | tail -1)
|
||||
[[ "${last,,}" != "${bios,,}"* ]] && return 1
|
||||
grep -Fq "No bootable device." "$QEMU_PTY" && return 1
|
||||
grep -Fq "BOOTMGR is missing" "$QEMU_PTY" && return 1
|
||||
return 0
|
||||
fi
|
||||
|
||||
local line="\"Windows Boot Manager\""
|
||||
grep -Fq "$line" "$QEMU_PTY" && return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
finish() {
|
||||
|
||||
local pid
|
||||
local reason=$1
|
||||
|
||||
touch "$QEMU_END"
|
||||
|
||||
if [ -s "$QEMU_PID" ]; then
|
||||
|
||||
pid=$(<"$QEMU_PID")
|
||||
error "Forcefully terminating Windows, reason: $reason..."
|
||||
{ kill -15 "$pid" || true; } 2>/dev/null
|
||||
|
||||
while isAlive "$pid"; do
|
||||
sleep 1
|
||||
# Workaround for zombie pid
|
||||
[ ! -s "$QEMU_PID" ] && break
|
||||
done
|
||||
fi
|
||||
|
||||
if [ ! -f "$STORAGE/windows.boot" ] && [ -f "$BOOT" ]; then
|
||||
# Remove CD-ROM ISO after install
|
||||
if ready; then
|
||||
touch "$STORAGE/windows.boot"
|
||||
if [[ "$REMOVE" != [Nn]* ]]; then
|
||||
rm -f "$BOOT" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
pid="/var/run/tpm.pid"
|
||||
[ -s "$pid" ] && pKill "$(<"$pid")"
|
||||
|
||||
pid="/var/run/wsdd.pid"
|
||||
[ -s "$pid" ] && pKill "$(<"$pid")"
|
||||
|
||||
fKill "smbd"
|
||||
|
||||
closeNetwork
|
||||
|
||||
sleep 0.5
|
||||
echo "❯ Shutdown completed!"
|
||||
|
||||
exit "$reason"
|
||||
}
|
||||
|
||||
terminal() {
|
||||
|
||||
local dev=""
|
||||
|
||||
if [ -s "$QEMU_OUT" ]; then
|
||||
|
||||
local msg
|
||||
msg=$(<"$QEMU_OUT")
|
||||
|
||||
if [ -n "$msg" ]; then
|
||||
|
||||
if [[ "${msg,,}" != "char"* || "$msg" != *"serial0)" ]]; then
|
||||
echo "$msg"
|
||||
fi
|
||||
|
||||
dev="${msg#*/dev/p}"
|
||||
dev="/dev/p${dev%% *}"
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -c "$dev" ]; then
|
||||
dev=$(echo 'info chardev' | nc -q 1 -w 1 localhost "$QEMU_PORT" | tr -d '\000')
|
||||
dev="${dev#*serial0}"
|
||||
dev="${dev#*pty:}"
|
||||
dev="${dev%%$'\n'*}"
|
||||
dev="${dev%%$'\r'*}"
|
||||
fi
|
||||
|
||||
if [ ! -c "$dev" ]; then
|
||||
error "Device '$dev' not found!"
|
||||
finish 34 && return 34
|
||||
fi
|
||||
|
||||
QEMU_TERM="$dev"
|
||||
return 0
|
||||
}
|
||||
|
||||
_graceful_shutdown() {
|
||||
|
||||
local code=$?
|
||||
|
||||
set +e
|
||||
|
||||
if [ -f "$QEMU_END" ]; then
|
||||
info "Received $1 while already shutting down..."
|
||||
return
|
||||
fi
|
||||
|
||||
touch "$QEMU_END"
|
||||
info "Received $1, sending ACPI shutdown signal..."
|
||||
|
||||
if [ ! -s "$QEMU_PID" ]; then
|
||||
error "QEMU PID file does not exist?"
|
||||
finish "$code" && return "$code"
|
||||
fi
|
||||
|
||||
local pid=""
|
||||
pid=$(<"$QEMU_PID")
|
||||
|
||||
if ! isAlive "$pid"; then
|
||||
error "QEMU process does not exist?"
|
||||
finish "$code" && return "$code"
|
||||
fi
|
||||
|
||||
if ! ready; then
|
||||
info "Cannot send ACPI signal during Windows setup, aborting..."
|
||||
finish "$code" && return "$code"
|
||||
fi
|
||||
|
||||
# Send ACPI shutdown signal
|
||||
echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_PORT}" > /dev/null
|
||||
|
||||
local cnt=0
|
||||
while [ "$cnt" -lt "$QEMU_TIMEOUT" ]; do
|
||||
|
||||
sleep 1
|
||||
cnt=$((cnt+1))
|
||||
|
||||
! isAlive "$pid" && break
|
||||
# Workaround for zombie pid
|
||||
[ ! -s "$QEMU_PID" ] && break
|
||||
|
||||
info "Waiting for Windows to shutdown... ($cnt/$QEMU_TIMEOUT)"
|
||||
|
||||
# Send ACPI shutdown signal
|
||||
echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_PORT}" > /dev/null
|
||||
|
||||
done
|
||||
|
||||
if [ "$cnt" -ge "$QEMU_TIMEOUT" ]; then
|
||||
error "Shutdown timeout reached, aborting..."
|
||||
fi
|
||||
|
||||
finish "$code" && return "$code"
|
||||
}
|
||||
|
||||
SERIAL="pty"
|
||||
MONITOR="telnet:localhost:$QEMU_PORT,server,nowait,nodelay"
|
||||
MONITOR+=" -daemonize -D $QEMU_LOG -pidfile $QEMU_PID"
|
||||
|
||||
_trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT
|
||||
|
||||
return 0
|
||||
109
computer_use_demo/windowshost/vm/buildcontainer/samba.sh
Normal file
109
computer_use_demo/windowshost/vm/buildcontainer/samba.sh
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
: "${SAMBA:="Y"}"
|
||||
|
||||
[[ "$SAMBA" == [Nn]* ]] && return 0
|
||||
[[ "$NETWORK" == [Nn]* ]] && return 0
|
||||
|
||||
hostname="host.lan"
|
||||
interface="dockerbridge"
|
||||
|
||||
if [[ "$DHCP" == [Yy1]* ]]; then
|
||||
hostname="$IP"
|
||||
interface="$VM_NET_DEV"
|
||||
fi
|
||||
|
||||
addShare() {
|
||||
local dir="$1"
|
||||
local name="$2"
|
||||
local comment="$3"
|
||||
|
||||
mkdir -p "$dir" || return 1
|
||||
|
||||
if [ -z "$(ls -A "$dir")" ]; then
|
||||
|
||||
chmod 777 "$dir"
|
||||
|
||||
{ echo "--------------------------------------------------------"
|
||||
echo " $APP"
|
||||
echo " For support visit $SUPPORT"
|
||||
echo "--------------------------------------------------------"
|
||||
echo ""
|
||||
echo "Using this folder you can share files with the host machine."
|
||||
echo ""
|
||||
echo "To change its location, include the following bind mount in your compose file:"
|
||||
echo ""
|
||||
echo " volumes:"
|
||||
echo " - \"/home/example:/${name,,}\""
|
||||
echo ""
|
||||
echo "Or in your run command:"
|
||||
echo ""
|
||||
echo " -v \"/home/example:/${name,,}\""
|
||||
echo ""
|
||||
echo "Replace the example path /home/example with the desired shared folder."
|
||||
echo ""
|
||||
} | unix2dos > "$dir/readme.txt"
|
||||
|
||||
fi
|
||||
|
||||
{ echo ""
|
||||
echo "[$name]"
|
||||
echo " path = $dir"
|
||||
echo " comment = $comment"
|
||||
echo " writable = yes"
|
||||
echo " guest ok = yes"
|
||||
echo " guest only = yes"
|
||||
echo " force user = root"
|
||||
echo " force group = root"
|
||||
} >> "/etc/samba/smb.conf"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
{ echo "[global]"
|
||||
echo " server string = Dockur"
|
||||
echo " netbios name = $hostname"
|
||||
echo " workgroup = WORKGROUP"
|
||||
echo " interfaces = $interface"
|
||||
echo " bind interfaces only = yes"
|
||||
echo " security = user"
|
||||
echo " guest account = nobody"
|
||||
echo " map to guest = Bad User"
|
||||
echo " server min protocol = NT1"
|
||||
echo ""
|
||||
echo " # disable printing services"
|
||||
echo " load printers = no"
|
||||
echo " printing = bsd"
|
||||
echo " printcap name = /dev/null"
|
||||
echo " disable spoolss = yes"
|
||||
} > "/etc/samba/smb.conf"
|
||||
|
||||
share="/data"
|
||||
[ ! -d "$share" ] && [ -d "$STORAGE/data" ] && share="$STORAGE/data"
|
||||
[ ! -d "$share" ] && [ -d "/shared" ] && share="/shared"
|
||||
[ ! -d "$share" ] && [ -d "$STORAGE/shared" ] && share="$STORAGE/shared"
|
||||
|
||||
addShare "$share" "Data" "Shared" || error "Failed to create shared folder!"
|
||||
|
||||
[ -d "/data2" ] && addShare "/data2" "Data2" "Shared"
|
||||
[ -d "/data3" ] && addShare "/data3" "Data3" "Shared"
|
||||
|
||||
if ! smbd; then
|
||||
error "Samba daemon failed to start!"
|
||||
smbd -i --debug-stdout || true
|
||||
fi
|
||||
|
||||
if [[ "${BOOT_MODE:-}" == "windows_legacy" ]]; then
|
||||
# Enable NetBIOS on Windows 7 and lower
|
||||
if ! nmbd; then
|
||||
error "NetBIOS daemon failed to start!"
|
||||
nmbd -i --debug-stdout || true
|
||||
fi
|
||||
else
|
||||
# Enable Web Service Discovery on Vista and up
|
||||
wsdd -i "$interface" -p -n "$hostname" &
|
||||
echo "$!" > /var/run/wsdd.pid
|
||||
fi
|
||||
|
||||
return 0
|
||||
@@ -0,0 +1,462 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<settings pass="windowsPE">
|
||||
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<SetupUILanguage>
|
||||
<UILanguage>en-US</UILanguage>
|
||||
</SetupUILanguage>
|
||||
<InputLocale>0409:00000409</InputLocale>
|
||||
<SystemLocale>en-US</SystemLocale>
|
||||
<UILanguage>en-US</UILanguage>
|
||||
<UserLocale>en-US</UserLocale>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<DiskConfiguration>
|
||||
<Disk wcm:action="add">
|
||||
<DiskID>0</DiskID>
|
||||
<WillWipeDisk>true</WillWipeDisk>
|
||||
<CreatePartitions>
|
||||
<!-- System partition (ESP) -->
|
||||
<CreatePartition wcm:action="add">
|
||||
<Order>1</Order>
|
||||
<Type>EFI</Type>
|
||||
<Size>128</Size>
|
||||
</CreatePartition>
|
||||
<!-- Microsoft reserved partition (MSR) -->
|
||||
<CreatePartition wcm:action="add">
|
||||
<Order>2</Order>
|
||||
<Type>MSR</Type>
|
||||
<Size>128</Size>
|
||||
</CreatePartition>
|
||||
<!-- Windows partition -->
|
||||
<CreatePartition wcm:action="add">
|
||||
<Order>3</Order>
|
||||
<Type>Primary</Type>
|
||||
<Extend>true</Extend>
|
||||
</CreatePartition>
|
||||
</CreatePartitions>
|
||||
<ModifyPartitions>
|
||||
<!-- System partition (ESP) -->
|
||||
<ModifyPartition wcm:action="add">
|
||||
<Order>1</Order>
|
||||
<PartitionID>1</PartitionID>
|
||||
<Label>System</Label>
|
||||
<Format>FAT32</Format>
|
||||
</ModifyPartition>
|
||||
<!-- MSR partition does not need to be modified -->
|
||||
<ModifyPartition wcm:action="add">
|
||||
<Order>2</Order>
|
||||
<PartitionID>2</PartitionID>
|
||||
</ModifyPartition>
|
||||
<!-- Windows partition -->
|
||||
<ModifyPartition wcm:action="add">
|
||||
<Order>3</Order>
|
||||
<PartitionID>3</PartitionID>
|
||||
<Label>Windows</Label>
|
||||
<Letter>C</Letter>
|
||||
<Format>NTFS</Format>
|
||||
</ModifyPartition>
|
||||
</ModifyPartitions>
|
||||
</Disk>
|
||||
</DiskConfiguration>
|
||||
<ImageInstall>
|
||||
<OSImage>
|
||||
<InstallTo>
|
||||
<DiskID>0</DiskID>
|
||||
<PartitionID>3</PartitionID>
|
||||
</InstallTo>
|
||||
<InstallToAvailablePartition>false</InstallToAvailablePartition>
|
||||
</OSImage>
|
||||
</ImageInstall>
|
||||
<DynamicUpdate>
|
||||
<Enable>true</Enable>
|
||||
<WillShowUI>Never</WillShowUI>
|
||||
</DynamicUpdate>
|
||||
<UpgradeData>
|
||||
<Upgrade>false</Upgrade>
|
||||
<WillShowUI>Never</WillShowUI>
|
||||
</UpgradeData>
|
||||
<UserData>
|
||||
<AcceptEula>true</AcceptEula>
|
||||
<FullName>Docker</FullName>
|
||||
<Organization>Windows for Docker</Organization>
|
||||
</UserData>
|
||||
<EnableFirewall>false</EnableFirewall>
|
||||
<Diagnostics>
|
||||
<OptIn>false</OptIn>
|
||||
</Diagnostics>
|
||||
<RunSynchronous>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>1</Order>
|
||||
<Path>reg.exe add "HKLM\SYSTEM\Setup\LabConfig" /v BypassTPMCheck /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>2</Order>
|
||||
<Path>reg.exe add "HKLM\SYSTEM\Setup\LabConfig" /v BypassSecureBootCheck /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>3</Order>
|
||||
<Path>reg.exe add "HKLM\SYSTEM\Setup\LabConfig" /v BypassRAMCheck /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>4</Order>
|
||||
<Path>reg.exe add "HKLM\SYSTEM\Setup\MoSetup" /v AllowUpgradesWithUnsupportedTPMOrCPU /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
</RunSynchronous>
|
||||
</component>
|
||||
</settings>
|
||||
<settings pass="offlineServicing">
|
||||
<component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<EnableLUA>false</EnableLUA>
|
||||
</component>
|
||||
</settings>
|
||||
<settings pass="generalize">
|
||||
<component name="Microsoft-Windows-PnPSysprep" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<PersistAllDeviceInstalls>true</PersistAllDeviceInstalls>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<SkipRearm>1</SkipRearm>
|
||||
</component>
|
||||
</settings>
|
||||
<settings pass="specialize">
|
||||
<component name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<SkipAutoActivation>true</SkipAutoActivation>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<ComputerName>*</ComputerName>
|
||||
<OEMInformation>
|
||||
<Manufacturer>Dockur</Manufacturer>
|
||||
<Model>Windows for Docker</Model>
|
||||
<SupportHours>24/7</SupportHours>
|
||||
<SupportPhone />
|
||||
<SupportProvider>Dockur</SupportProvider>
|
||||
<SupportURL>https://github.com/dockur/windows/issues</SupportURL>
|
||||
</OEMInformation>
|
||||
<OEMName>Windows for Docker</OEMName>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-ErrorReportingCore" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<DisableWER>1</DisableWER>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-IE-InternetExplorer" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<DisableAccelerators>true</DisableAccelerators>
|
||||
<DisableFirstRunWizard>true</DisableFirstRunWizard>
|
||||
<Home_Page>https://google.com</Home_Page>
|
||||
<Help_Page>about:blank</Help_Page>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-IE-InternetExplorer" processorArchitecture="wow64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<DisableAccelerators>true</DisableAccelerators>
|
||||
<DisableFirstRunWizard>true</DisableFirstRunWizard>
|
||||
<Home_Page>https://google.com</Home_Page>
|
||||
<Help_Page>about:blank</Help_Page>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-SQMApi" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<CEIPEnabled>0</CEIPEnabled>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-SystemRestore-Main" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<DisableSR>1</DisableSR>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<InputLocale>0409:00000409</InputLocale>
|
||||
<SystemLocale>en-US</SystemLocale>
|
||||
<UILanguage>en-US</UILanguage>
|
||||
<UserLocale>en-US</UserLocale>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<RunSynchronous>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>1</Order>
|
||||
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v BypassNRO /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>2</Order>
|
||||
<Path>reg.exe load "HKU\mount" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>3</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "ContentDeliveryAllowed" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>4</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "FeatureManagementEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>5</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "OEMPreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>6</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>7</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEverEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>8</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SilentInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>9</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SoftLandingEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>10</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContentEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>11</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-310093Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>12</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338387Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>13</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338388Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>14</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338389Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>15</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338393Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>16</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353698Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>17</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SystemPaneSuggestionsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>18</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableCloudOptimizedContent" /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>19</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>20</Order>
|
||||
<Path>reg.exe add "HKU\mount\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableConsumerAccountStateContent" /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>21</Order>
|
||||
<Path>reg.exe unload "HKU\mount"</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>22</Order>
|
||||
<Path>reg.exe add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableCloudOptimizedContent" /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>23</Order>
|
||||
<Path>reg.exe add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>24</Order>
|
||||
<Path>reg.exe add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableConsumerAccountStateContent" /t REG_DWORD /d 1 /f</Path>
|
||||
</RunSynchronousCommand>
|
||||
<RunSynchronousCommand wcm:action="add">
|
||||
<Order>25</Order>
|
||||
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\FirstNetwork" /v Category /t REG_DWORD /d 1 /f</Path>
|
||||
<Description>Set Network Location to Home</Description>
|
||||
</RunSynchronousCommand>
|
||||
</RunSynchronous>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<fDenyTSConnections>false</fDenyTSConnections>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-TerminalServices-RDP-WinStationExtensions" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<UserAuthentication>0</UserAuthentication>
|
||||
</component>
|
||||
<component name="Networking-MPSSVC-Svc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<FirewallGroups>
|
||||
<FirewallGroup wcm:action="add" wcm:keyValue="RemoteDesktop">
|
||||
<Active>true</Active>
|
||||
<Profile>all</Profile>
|
||||
<Group>@FirewallAPI.dll,-28752</Group>
|
||||
</FirewallGroup>
|
||||
</FirewallGroups>
|
||||
</component>
|
||||
</settings>
|
||||
<settings pass="auditSystem" />
|
||||
<settings pass="auditUser" />
|
||||
<settings pass="oobeSystem">
|
||||
<component name="Microsoft-Windows-SecureStartup-FilterDriver" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<PreventDeviceEncryption>true</PreventDeviceEncryption>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-EnhancedStorage-Adm" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<TCGSecurityActivationDisabled>1</TCGSecurityActivationDisabled>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<UserAccounts>
|
||||
<LocalAccounts>
|
||||
<LocalAccount wcm:action="add">
|
||||
<Name>Docker</Name>
|
||||
<Group>Administrators</Group>
|
||||
<Password>
|
||||
<Value />
|
||||
<PlainText>true</PlainText>
|
||||
</Password>
|
||||
</LocalAccount>
|
||||
</LocalAccounts>
|
||||
<AdministratorPassword>
|
||||
<Value>password</Value>
|
||||
<PlainText>true</PlainText>
|
||||
</AdministratorPassword>
|
||||
</UserAccounts>
|
||||
<AutoLogon>
|
||||
<Username>Docker</Username>
|
||||
<Enabled>true</Enabled>
|
||||
<LogonCount>65432</LogonCount>
|
||||
<Password>
|
||||
<Value />
|
||||
<PlainText>true</PlainText>
|
||||
</Password>
|
||||
</AutoLogon>
|
||||
<Display>
|
||||
<ColorDepth>32</ColorDepth>
|
||||
<HorizontalResolution>1920</HorizontalResolution>
|
||||
<VerticalResolution>1080</VerticalResolution>
|
||||
</Display>
|
||||
<OOBE>
|
||||
<HideEULAPage>true</HideEULAPage>
|
||||
<HideLocalAccountScreen>true</HideLocalAccountScreen>
|
||||
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
|
||||
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
|
||||
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
|
||||
<NetworkLocation>Home</NetworkLocation>
|
||||
<ProtectYourPC>3</ProtectYourPC>
|
||||
<SkipUserOOBE>true</SkipUserOOBE>
|
||||
<SkipMachineOOBE>true</SkipMachineOOBE>
|
||||
</OOBE>
|
||||
<RegisteredOrganization>Dockur</RegisteredOrganization>
|
||||
<RegisteredOwner>Windows for Docker</RegisteredOwner>
|
||||
<FirstLogonCommands>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>1</Order>
|
||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "AllowInsecureGuestAuth" /t REG_DWORD /d 1 /f</CommandLine>
|
||||
<Description>Allow guest access to network shares</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>2</Order>
|
||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "RequireSecuritySignature" /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<Description>Disable SMB signing requirement</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>3</Order>
|
||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<Description>Allow RDP login with blank password</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>4</Order>
|
||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<Description>Enable option for passwordless sign-in</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>5</Order>
|
||||
<CommandLine>cmd /C wmic useraccount where name="Docker" set PasswordExpires=false</CommandLine>
|
||||
<Description>Password Never Expires</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>6</Order>
|
||||
<CommandLine>cmd /C POWERCFG -H OFF</CommandLine>
|
||||
<Description>Disable Hibernation</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>7</Order>
|
||||
<CommandLine>cmd /C POWERCFG -X -monitor-timeout-ac 0</CommandLine>
|
||||
<Description>Disable monitor blanking</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>8</Order>
|
||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Edge" /v "HideFirstRunExperience" /t REG_DWORD /d 1 /f</CommandLine>
|
||||
<Description>Disable first-run experience in Edge</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>9</Order>
|
||||
<CommandLine>reg.exe add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "HideFileExt" /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<Description>Show file extensions in Explorer</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>10</Order>
|
||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Power" /v "HibernateFileSizePercent" /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<Description>Zero Hibernation File</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>11</Order>
|
||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Power" /v "HibernateEnabled" /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<Description>Disable Hibernation</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>12</Order>
|
||||
<CommandLine>cmd /C POWERCFG -X -standby-timeout-ac 0</CommandLine>
|
||||
<Description>Disable Sleep</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>13</Order>
|
||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v "fAllowUnlistedRemotePrograms" /t REG_DWORD /d 1 /f</CommandLine>
|
||||
<Description>Enable RemoteAPP to launch unlisted programs</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>14</Order>
|
||||
<CommandLine>reg.exe add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "ShowTaskViewButton" /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<Description>Remove Task View from the Taskbar</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>15</Order>
|
||||
<CommandLine>reg.exe add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "TaskbarDa" /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<Description>Remove Widgets from the Taskbar</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>16</Order>
|
||||
<CommandLine>reg.exe add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "TaskbarMn" /t REG_DWORD /d 0 /f</CommandLine>
|
||||
<Description>Remove Chat from the Taskbar</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>17</Order>
|
||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" /v "NoAutoUpdate" /t REG_DWORD /d 1 /f</CommandLine>
|
||||
<Description>Turn off Windows Update auto download</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>18</Order>
|
||||
<CommandLine>netsh advfirewall firewall set rule group="@FirewallAPI.dll,-32752" new enable=Yes</CommandLine>
|
||||
<Description>Enable Network Discovery</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>19</Order>
|
||||
<CommandLine>netsh advfirewall firewall set rule group="@FirewallAPI.dll,-28502" new enable=Yes</CommandLine>
|
||||
<Description>Enable File Sharing</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>20</Order>
|
||||
<CommandLine>reg.exe add "HKCU\Control Panel\UnsupportedHardwareNotificationCache" /v SV1 /d 0 /t REG_DWORD /f</CommandLine>
|
||||
<Description>Disable unsupported hardware notifications</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>21</Order>
|
||||
<CommandLine>reg.exe add "HKCU\Control Panel\UnsupportedHardwareNotificationCache" /v SV2 /d 0 /t REG_DWORD /f</CommandLine>
|
||||
<Description>Disable unsupported hardware notifications</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>22</Order>
|
||||
<CommandLine>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</CommandLine>
|
||||
<Description>Install VirtIO display driver</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>23</Order>
|
||||
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
||||
<Description>Remove empty Windows.old folder</Description>
|
||||
</SynchronousCommand>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Order>24</Order>
|
||||
<CommandLine>cmd /C if exist "C:\OEM\install.bat" start "Install" "cmd /C C:\OEM\install.bat"</CommandLine>
|
||||
<Description>Execute custom script from the OEM folder if exists</Description>
|
||||
</SynchronousCommand>
|
||||
</FirstLogonCommands>
|
||||
</component>
|
||||
</settings>
|
||||
</unattend>
|
||||
1
computer_use_demo/windowshost/vm/win11iso/README.md
Normal file
1
computer_use_demo/windowshost/vm/win11iso/README.md
Normal file
@@ -0,0 +1 @@
|
||||
Add your Win11E setup.iso to this folder
|
||||
@@ -0,0 +1,31 @@
|
||||
@echo off
|
||||
|
||||
SET ScriptFolder=\\host.lan\Data
|
||||
SET LogFile=%ScriptFolder%\firstboot_log.txt
|
||||
|
||||
echo Running PowerShell script... > %LogFile%
|
||||
|
||||
:: Check for PowerShell availability
|
||||
where powershell >> %LogFile% 2>&1
|
||||
if %ERRORLEVEL% neq 0 (
|
||||
echo PowerShell is not available! >> %LogFile%
|
||||
echo PowerShell is not available!
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: Add a 30-second delay
|
||||
echo Waiting for 30 seconds before continuing... >> %LogFile%
|
||||
timeout /t 30 /nobreak >> %LogFile% 2>&1
|
||||
|
||||
:: Run PowerShell script with ExecutionPolicy Bypass and log errors
|
||||
echo Running setup.ps1... >> %LogFile%
|
||||
|
||||
powershell -ExecutionPolicy Bypass -File "%ScriptFolder%\setup.ps1" >> %LogFile% 2>&1
|
||||
|
||||
if %ERRORLEVEL% neq 0 (
|
||||
echo An error occurred. See %LogFile% for details.
|
||||
) else (
|
||||
echo PowerShell script has completed successfully.
|
||||
)
|
||||
|
||||
echo PowerShell script has completed.
|
||||
@@ -0,0 +1,7 @@
|
||||
$scriptFolder = "\\host.lan\Data"
|
||||
$pythonScriptFile = "$scriptFolder\server\main.py"
|
||||
$pythonServerPort = 5000
|
||||
|
||||
# Start the flask computer use server
|
||||
Write-Host "Running the server on port $pythonServerPort"
|
||||
python $pythonScriptFile --port $pythonServerPort
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,81 @@
|
||||
import os
|
||||
import logging
|
||||
import argparse
|
||||
import shlex
|
||||
import subprocess
|
||||
from flask import Flask, request, jsonify, send_file
|
||||
import threading
|
||||
import traceback
|
||||
import pyautogui
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--log_file", help="log file path", type=str,
|
||||
default=os.path.join(os.path.dirname(__file__), "server.log"))
|
||||
parser.add_argument("--port", help="port", type=int, default=5000)
|
||||
args = parser.parse_args()
|
||||
|
||||
logging.basicConfig(filename=args.log_file,level=logging.DEBUG, filemode='w' )
|
||||
logger = logging.getLogger('werkzeug')
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
computer_control_lock = threading.Lock()
|
||||
|
||||
@app.route('/probe', methods=['GET'])
|
||||
def probe_endpoint():
|
||||
return jsonify({"status": "Probe successful", "message": "Service is operational"}), 200
|
||||
|
||||
@app.route('/execute', methods=['POST'])
|
||||
def execute_command():
|
||||
# Only execute one command at a time
|
||||
with computer_control_lock:
|
||||
data = request.json
|
||||
# The 'command' key in the JSON request should contain the command to be executed.
|
||||
shell = data.get('shell', False)
|
||||
command = data.get('command', "" if shell else [])
|
||||
|
||||
if isinstance(command, str) and not shell:
|
||||
command = shlex.split(command)
|
||||
|
||||
# Expand user directory
|
||||
for i, arg in enumerate(command):
|
||||
if arg.startswith("~/"):
|
||||
command[i] = os.path.expanduser(arg)
|
||||
|
||||
# Execute the command without any safety checks.
|
||||
try:
|
||||
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=shell, text=True, timeout=120)
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'output': result.stdout,
|
||||
'error': result.stderr,
|
||||
'returncode': result.returncode
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error("\n" + traceback.format_exc() + "\n")
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': str(e)
|
||||
}), 500
|
||||
|
||||
@app.route('/screenshot', methods=['GET'])
|
||||
def capture_screen_with_cursor():
|
||||
cursor_path = os.path.join(os.path.dirname(__file__), "cursor.png")
|
||||
screenshot = pyautogui.screenshot()
|
||||
cursor_x, cursor_y = pyautogui.position()
|
||||
cursor = Image.open(cursor_path)
|
||||
# make the cursor smaller
|
||||
cursor = cursor.resize((int(cursor.width / 1.5), int(cursor.height / 1.5)))
|
||||
screenshot.paste(cursor, (cursor_x, cursor_y), cursor)
|
||||
|
||||
|
||||
# Convert PIL Image to bytes and send
|
||||
img_io = BytesIO()
|
||||
screenshot.save(img_io, 'PNG')
|
||||
img_io.seek(0)
|
||||
return send_file(img_io, mimetype='image/png')
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host="0.0.0.0", port=args.port)
|
||||
@@ -0,0 +1,2 @@
|
||||
flask
|
||||
PyAutoGUI
|
||||
@@ -0,0 +1,197 @@
|
||||
function Get-Tools {
|
||||
param(
|
||||
[string]$toolsConfigJson
|
||||
)
|
||||
|
||||
# Convert the JSON string to a PowerShell object
|
||||
$toolsList = $toolsConfigJson | ConvertFrom-Json
|
||||
|
||||
return $toolsList
|
||||
}
|
||||
|
||||
function Get-ToolDetails {
|
||||
param(
|
||||
$toolsList,
|
||||
[string]$toolName
|
||||
)
|
||||
|
||||
# Check if the program exists in the JSON data
|
||||
if ($toolsList.PSObject.Properties.Name -contains $toolName) {
|
||||
# Return the program details as a PowerShell object
|
||||
return $toolsList.$toolName
|
||||
} else {
|
||||
# Handle the case where the program is not found
|
||||
Write-Host "Program '$toolName' not found in the list."
|
||||
return $null
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-DownloadFileFromAvailableMirrors {
|
||||
param (
|
||||
[string[]]$mirrorUrls,
|
||||
[string]$outfile
|
||||
)
|
||||
foreach ($url in $mirrorUrls) {
|
||||
try {
|
||||
$result = Invoke-DownloadFile -url $url -outfile $outfile
|
||||
if ($result -eq $true) {
|
||||
Write-Host "Downloaded using $url"
|
||||
return $true
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Error downloading from $url. Please check and update the mirrors."
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Downloading from the provided mirrors failed. Please check and update the mirrors."
|
||||
return $false
|
||||
}
|
||||
|
||||
function Invoke-DownloadFile {
|
||||
param (
|
||||
[string]$url,
|
||||
[string]$outfile
|
||||
)
|
||||
# Makes download faster by disabling progress bar
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
$retryCount = 0
|
||||
$maxRetries = 3
|
||||
$sleepSeconds = 2
|
||||
$maxSleepSeconds = 10
|
||||
$userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
|
||||
|
||||
# Ensure directory exists
|
||||
$directory = Split-Path -Path $outfile -Parent
|
||||
if (-Not (Test-Path -Path $directory)) {
|
||||
Write-Host "Creating directory $directory..."
|
||||
New-Item -Path $directory -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
|
||||
while ($retryCount -lt $maxRetries) {
|
||||
try {
|
||||
Invoke-RestMethod -Uri $url -OutFile $outfile -Headers @{"User-Agent" = $userAgent}
|
||||
Write-Host "Download successful, file saved to: $outfile"
|
||||
break
|
||||
} catch {
|
||||
$retryCount++
|
||||
Write-Host "Attempt $retryCount of $maxRetries failed. Error: $($_.Exception.Message)"
|
||||
Start-Sleep -Seconds $sleepSeconds
|
||||
$sleepSeconds = [Math]::Min($sleepSeconds * 2, $maxSleepSeconds) # Exponential backoff with a cap
|
||||
}
|
||||
}
|
||||
|
||||
if ($retryCount -eq $maxRetries) {
|
||||
Write-Host "Failed to download the file after $maxRetries attempts."
|
||||
return $false
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
function Add-ToEnvPath {
|
||||
param (
|
||||
[string]$NewPath
|
||||
)
|
||||
|
||||
# Get the current PATH environment variable
|
||||
$envPath = [Environment]::GetEnvironmentVariable("PATH", "Machine")
|
||||
|
||||
# Append the new path to the existing PATH
|
||||
$newPath = "$envPath;$NewPath"
|
||||
|
||||
# Set the updated PATH environment variable
|
||||
[Environment]::SetEnvironmentVariable("PATH", $newPath, "Machine")
|
||||
|
||||
# Fetch updates from the shell
|
||||
$env:PATH += ";${newPath}"
|
||||
}
|
||||
|
||||
function Register-LogonTask {
|
||||
param(
|
||||
|
||||
[parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "Name of the scheduled task")]
|
||||
[string]
|
||||
$TaskName,
|
||||
|
||||
[parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "Path to the .py script")]
|
||||
[string]
|
||||
$ScriptPath,
|
||||
|
||||
[parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = "Arguments to the .py script")]
|
||||
[string]
|
||||
$Arguments = "",
|
||||
|
||||
[parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = "Local Account username")]
|
||||
[string]
|
||||
$LocalUser,
|
||||
|
||||
[parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = "Local Account password")]
|
||||
[string]
|
||||
$LocalPassword,
|
||||
|
||||
[parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = "Whether to execute the command as SYSTEM")]
|
||||
[switch]
|
||||
$AsSystem = $false,
|
||||
|
||||
[parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = "logging file")]
|
||||
[string]
|
||||
$LogFilePath
|
||||
)
|
||||
|
||||
$scriptDirectory = Split-Path $ScriptPath
|
||||
|
||||
$taskActionArgument = "-ExecutionPolicy Bypass -windowstyle hidden -Command `"try { . '$ScriptPath' $Arguments } catch { Write `$_.Exception.Message | Out-File $($TaskName)_Log.txt } finally { } `""
|
||||
$taskAction = New-ScheduledTaskAction -Execute "$PSHome\powershell.exe" -Argument $taskActionArgument -WorkingDirectory $scriptDirectory
|
||||
|
||||
$params = @{
|
||||
Force = $True
|
||||
Action = $taskAction
|
||||
RunLevel = "Highest"
|
||||
TaskName = $TaskName
|
||||
}
|
||||
|
||||
$taskTrigger = New-ScheduledTaskTrigger -AtLogOn
|
||||
$params.Add("Trigger", $taskTrigger)
|
||||
|
||||
if ($AsSystem) {
|
||||
$params.Add("User", "NT AUTHORITY\SYSTEM")
|
||||
}
|
||||
else {
|
||||
$params.Add("User", $LocalUser)
|
||||
if ($LocalPassword) {
|
||||
$params.Add("Password", $LocalPassword)
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Registering scheduled task '$TaskName' to run 'powershell.exe $taskActionArgument'..."
|
||||
Register-ScheduledTask @params
|
||||
}
|
||||
|
||||
# Function to attempt pip install and handle failures
|
||||
function Install-PythonPackages {
|
||||
param (
|
||||
[string]$Package = "",
|
||||
[string]$Arguments = "",
|
||||
[string]$RequirementsPath = ""
|
||||
)
|
||||
$RetryCount = 3
|
||||
$currentAttempt = 0
|
||||
while ($currentAttempt -lt $RetryCount) {
|
||||
if (-not [string]::IsNullOrWhiteSpace($RequirementsPath)) {
|
||||
& python -m pip install --no-cache-dir -r $RequirementsPath $Arguments
|
||||
} else {
|
||||
& python -m pip install --no-cache-dir $Package $Arguments
|
||||
}
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "Installation successful."
|
||||
return
|
||||
} else {
|
||||
Write-Host "Attempt $($currentAttempt + 1) failed. Retrying..."
|
||||
Start-Sleep -Seconds 10
|
||||
$currentAttempt++
|
||||
}
|
||||
}
|
||||
Write-Error "Failed to install after $RetryCount attempts."
|
||||
exit
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
$ErrorActionPreference = "Continue" # until downloading from mirrors is more stable
|
||||
|
||||
# Section - General Setup
|
||||
$scriptFolder = "\\host.lan\Data"
|
||||
$toolsFolder = "C:\Users\$env:USERNAME\Tools"
|
||||
|
||||
# Load the shared setup-tools module
|
||||
Import-Module (Join-Path $scriptFolder -ChildPath "setup-tools.psm1")
|
||||
|
||||
# Check if profile exists
|
||||
if (-not (Test-Path $PROFILE)) {
|
||||
New-Item -ItemType File -Path $PROFILE -Force
|
||||
}
|
||||
|
||||
# Create a folder where we store all the standalone executables
|
||||
if (-not (Test-Path $toolsFolder)) {
|
||||
New-Item -ItemType Directory -Path $toolsFolder -Force
|
||||
$envPath = [Environment]::GetEnvironmentVariable("PATH", "Machine")
|
||||
$newPath = "$envPath;$toolsFolder"
|
||||
[Environment]::SetEnvironmentVariable("PATH", $newPath, "Machine")
|
||||
}
|
||||
|
||||
# Section - Tools Installation
|
||||
|
||||
# Set TLS version to 1.2 or higher
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
|
||||
|
||||
# Load the tools config json listing mirrors and aliases used for installing tools
|
||||
$toolsConfigJsonPath = Join-Path $scriptFolder -ChildPath "tools_config.json"
|
||||
$toolsConfigJson = Get-Content -Path $toolsConfigJsonPath -Raw
|
||||
$toolsList = Get-Tools -toolsConfigJson $toolsConfigJson
|
||||
|
||||
## - Python
|
||||
$pythonToolName = "Python"
|
||||
$userPythonPath = "$env:LOCALAPPDATA\Programs\Python"
|
||||
$pythonDetails = Get-ToolDetails -toolsList $toolsList -toolName $pythonToolName
|
||||
$pythonAlias = $pythonDetails.alias
|
||||
|
||||
# Check for Python installation
|
||||
$pythonExecutablePath = Get-ChildItem -Path $userPythonPath -Filter python.exe -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
|
||||
|
||||
# Force to install Python 3.10 as the pre-installed version on Windows may not work sometimes
|
||||
Write-Host "Downloading Python $pythonVersion..."
|
||||
$pythonInstallerFilePath = "$env:TEMP\python_installer.exe"
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $pythonDetails.mirrors -outfile $pythonInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download Python. Please try again later or install manually."
|
||||
} else {
|
||||
Write-Host "Installing Python for current user..."
|
||||
Start-Process -FilePath $pythonInstallerFilePath -Args "/quiet InstallAllUsers=0 PrependPath=0" -NoNewWindow -Wait
|
||||
$pythonExecutablePath = "$userPythonPath\Python310\python.exe"
|
||||
$setAliasExpression = "Set-Alias -Name $pythonAlias -Value `"$pythonExecutablePath`""
|
||||
Add-Content -Path $PROFILE -Value $setAliasExpression
|
||||
Invoke-Expression $setAliasExpression
|
||||
}
|
||||
|
||||
## - Git
|
||||
$gitToolName = "git"
|
||||
$gitToolDetails = Get-ToolDetails -toolsList $toolsList -toolName $gitToolName
|
||||
|
||||
# Check for Git installation
|
||||
try {
|
||||
git --version | Out-Null
|
||||
Write-Host "Git is already installed."
|
||||
} catch {
|
||||
Write-Host "Git is not installed. Downloading and installing Git..."
|
||||
$gitInstallerFilePath = "$env:TEMP\git_installer.exe"
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $gitToolDetails.mirrors -outfile $gitInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download Git. Please try again later or install manually."
|
||||
} else {
|
||||
Start-Process -FilePath $gitInstallerFilePath -Args "/VERYSILENT /NORESTART /NOCANCEL /SP-" -Wait
|
||||
Add-ToEnvPath -NewPath "C:\Program Files\Git\bin"
|
||||
|
||||
Write-Host "Git has been installed."
|
||||
}
|
||||
}
|
||||
|
||||
# - 7zip
|
||||
$7ZipToolName = "7zip"
|
||||
$7ZipToolDetails = Get-ToolDetails -toolsList $toolsList -toolName $7ZipToolName
|
||||
Write-Host "$7ZipToolDetails"
|
||||
|
||||
if (Get-Command 7z -ErrorAction SilentlyContinue) {
|
||||
Write-Host "7-Zip is already installed."
|
||||
}
|
||||
else {
|
||||
Write-Host "Installing 7-Zip..."
|
||||
|
||||
$7ZipInstallerFilePath = "$env:TEMP\7_zip.exe"
|
||||
Write-Host "$($7ZipToolDetails.mirrors)"
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $7ZipToolDetails.mirrors -outfile $7ZipInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download 7-Zip. Please try again later or install manually."
|
||||
} else {
|
||||
Start-Process -FilePath $7ZipInstallerFilePath -Args "/S" -Verb RunAs -Wait
|
||||
Remove-Item $7ZipInstallerFilePath
|
||||
|
||||
# add 7z to PATH
|
||||
Add-ToEnvPath -NewPath "${env:ProgramFiles}\7-Zip"
|
||||
}
|
||||
}
|
||||
|
||||
# - ffpmeg
|
||||
$ffpmegToolName = "ffmpeg"
|
||||
$ffpmegToolDetails = Get-ToolDetails -toolsList $toolsList -toolName $ffpmegToolName
|
||||
|
||||
if (Get-Command ffmpeg -ErrorAction SilentlyContinue) {
|
||||
Write-Host "ffmpeg is already installed."
|
||||
} else {
|
||||
Write-Host "ffmpeg is not installed. Installing it."
|
||||
$ffpmegInstallerFilePath = "C:\ffmpeg.7z"
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $ffpmegToolDetails.mirrors -outfile $ffpmegInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download ffmpeg. Please try again later or install manually."
|
||||
} else {
|
||||
Write-Host "Extracting $ffpmegInstallerFilePath..."
|
||||
7z x -y -o"C:\" "C:\ffmpeg.7z"
|
||||
|
||||
$ffmpegFolder = Get-ChildItem -Path "C:\" -Filter "ffmpeg-*" -Directory
|
||||
$ffmpegFolder = -join ("C:\", $ffmpegFolder)
|
||||
#remove ffmpeg folder if exists
|
||||
if (Test-Path "C:\ffmpeg") {
|
||||
Remove-Item -Path "C:\ffmpeg" -Recurse -Force
|
||||
}
|
||||
Rename-Item -Path "$ffmpegFolder" -NewName "ffmpeg"
|
||||
|
||||
Write-Host "Adding ffmpeg to PATH..."
|
||||
Add-ToEnvPath -NewPath "C:\ffmpeg\bin"
|
||||
|
||||
Write-Host "ffmpeg is installed"
|
||||
}
|
||||
}
|
||||
|
||||
# Disable Edge Auto Updates
|
||||
Stop-Process -Name "MicrosoftEdgeUpdate" -Force -ErrorAction SilentlyContinue
|
||||
$edgeUpdatePath = "${env:ProgramFiles(x86)}\Microsoft\EdgeUpdate"
|
||||
Remove-Item -Path $edgeUpdatePath -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "Edge Update processes terminated and directory removed."
|
||||
|
||||
# - Google Chrome
|
||||
$chromeToolName = "Google Chrome"
|
||||
$chromeToolDetails = Get-ToolDetails -toolsList $toolsList -toolName $chromeToolName
|
||||
$chromeExePath = "C:\Program Files\Google\Chrome\Application\chrome.exe"
|
||||
$chromeAlias = $chromeToolDetails.alias
|
||||
|
||||
# Check if Google Chrome is already installed by its alias
|
||||
if (Get-Command $chromeAlias -ErrorAction SilentlyContinue) {
|
||||
Write-Host "Google Chrome is already installed."
|
||||
} else {
|
||||
# Download the installer to the Temp directory
|
||||
$chromeInstallerFilePath = "$env:TEMP\chrome_installer.exe"
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $chromeToolDetails.mirrors -outfile $chromeInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download Google Chrome. Please try again later or install manually."
|
||||
} else {
|
||||
# Execute the installer silently with elevated permissions
|
||||
Start-Process -FilePath $chromeInstallerFilePath -ArgumentList "/silent", "/install" -Verb RunAs -Wait
|
||||
|
||||
# Remove the installer file after installation
|
||||
Remove-Item -Path $chromeInstallerFilePath
|
||||
|
||||
# Set alias
|
||||
$setAliasExpression = "Set-Alias -Name $chromeAlias -Value `"$chromeExePath`""
|
||||
Add-Content -Path $PROFILE -Value $setAliasExpression
|
||||
Invoke-Expression $setAliasExpression
|
||||
|
||||
# Add Chrome to the system PATH environment variable
|
||||
Add-ToEnvPath -NewPath "${env:ProgramFiles}\Google\Chrome\Application"
|
||||
|
||||
# Disable Google Chrome Auto Updates
|
||||
$chromeRegPath = "HKLM:\SOFTWARE\Policies\Google\Update"
|
||||
if (-not (Test-Path $chromeRegPath)) {
|
||||
New-Item -Path $chromeRegPath -Force
|
||||
}
|
||||
Set-ItemProperty -Path $chromeRegPath -Name "AutoUpdateCheckPeriodMinutes" -Value 0
|
||||
Set-ItemProperty -Path $chromeRegPath -Name "UpdateDefault" -Value 0
|
||||
}
|
||||
}
|
||||
|
||||
# - LibreOffice
|
||||
$libreOfficeToolName = "LibreOffice"
|
||||
$libreOfficeToolDetails = Get-ToolDetails -toolsList $toolsList -toolName $libreOfficeToolName
|
||||
|
||||
# Check for LibreOffice installation
|
||||
$installedVersion = (Get-WmiObject -Query "SELECT * FROM Win32_Product WHERE Name like 'LibreOffice%'").Version
|
||||
if (-not [string]::IsNullOrWhiteSpace($installedVersion)) {
|
||||
Write-Host "LibreOffice $version is already installed."
|
||||
} else {
|
||||
Write-Host "LibreOffice is not installed. Downloading and installing LibreOffice..."
|
||||
$libreOfficeInstallerFilePath = "$env:TEMP\libreOffice_installer.exe"
|
||||
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $libreOfficeToolDetails.mirrors -outfile $libreOfficeInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download LibreOffice. Please try again later or install manually."
|
||||
} else {
|
||||
Start-Process "msiexec.exe" -ArgumentList "/i `"$libreOfficeInstallerFilePath`" /quiet" -Wait -NoNewWindow
|
||||
Write-Host "LibreOffice has been installed."
|
||||
|
||||
# Add LibreOffice to the system PATH environment variable
|
||||
Add-ToEnvPath -NewPath "C:\Program Files\LibreOffice\program"
|
||||
}
|
||||
}
|
||||
|
||||
# - VLC
|
||||
$vlcToolName = "VLC"
|
||||
$vlcToolDetails = Get-ToolDetails -toolsList $toolsList -toolName $vlcToolName
|
||||
$vlcAlias = $vlcToolDetails.alias
|
||||
$vlcExecutableFilePath = "C:\Program Files\VideoLAN\VLC\vlc.exe"
|
||||
|
||||
# Check if VLC is already installed by checking the VLC command
|
||||
if (Test-Path $vlcExecutableFilePath) {
|
||||
Write-Host "VLC is already installed."
|
||||
} else {
|
||||
# Download the installer to the Temp directory
|
||||
$vlcInstallerFilePath = "$env:TEMP\vlc_installer.exe"
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $vlcToolDetails.mirrors -outfile $vlcInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download VLC. Please try again later or install manually."
|
||||
} else {
|
||||
# Execute the installer silently with elevated permissions
|
||||
Start-Process -FilePath $vlcInstallerFilePath -ArgumentList "/S" -Verb RunAs -Wait
|
||||
|
||||
# Remove the installer file after installation
|
||||
Remove-Item -Path $vlcInstallerFilePath
|
||||
|
||||
# Set alias
|
||||
$setAliasExpression = "Set-Alias -Name $vlcAlias -Value `"$vlcExecutableFilePath`""
|
||||
Add-Content -Path $PROFILE -Value $setAliasExpression
|
||||
Invoke-Expression $setAliasExpression
|
||||
|
||||
# Add VLC to the system PATH environment variable
|
||||
Add-ToEnvPath -NewPath "C:\Program Files\VideoLAN\VLC"
|
||||
}
|
||||
}
|
||||
|
||||
# - GIMP
|
||||
$gimpToolName = "GIMP"
|
||||
$gimpToolDetails = Get-ToolDetails -toolsList $toolsList -toolName $gimpToolName
|
||||
$gimpAlias = $gimpToolDetails.alias
|
||||
$gimpExecutablePath = "C:\Program Files\GIMP 2\bin\gimp-2.10.exe"
|
||||
|
||||
# Check if GIMP is already installed by checking the GIMP executable path
|
||||
if (Test-Path $gimpExecutablePath) {
|
||||
Write-Host "GIMP is already installed."
|
||||
} else {
|
||||
# Download the installer to the Temp directory
|
||||
$gimpInstallerFilePath = "$env:TEMP\gimp_installer.exe"
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $gimpToolDetails.mirrors -outfile $gimpInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download GIMP. Please try again later or install manually."
|
||||
} else {
|
||||
# Execute the installer silently with elevated permissions
|
||||
Start-Process -FilePath $gimpInstallerFilePath -ArgumentList "/VERYSILENT /ALLUSERS" -Verb RunAs -Wait
|
||||
|
||||
# Remove the installer file after installation
|
||||
Remove-Item -Path $gimpInstallerFilePath
|
||||
|
||||
# Set alias
|
||||
$setAliasExpression = "Set-Alias -Name $gimpAlias -Value `"$gimpExecutablePath`""
|
||||
Add-Content -Path $PROFILE -Value $setAliasExpression
|
||||
Invoke-Expression $setAliasExpression
|
||||
|
||||
# Add GIMP to the system PATH environment variable
|
||||
Add-ToEnvPath -NewPath "C:\Program Files\GIMP 2\bin"
|
||||
}
|
||||
}
|
||||
|
||||
# - VS Code
|
||||
$vsCodeToolName = "VS Code"
|
||||
$vsCodeToolDetails = Get-ToolDetails -toolsList $toolsList -toolName $vsCodeToolName
|
||||
$vsCodeAlias = $gimpToolDetails.alias
|
||||
$vsCodeExecutablePath = "C:\Users\$env:USERNAME\AppData\Local\Programs\Microsoft VS Code\Code.exe"
|
||||
|
||||
# Check if VS Code is already installed by checking the VS Code executable path
|
||||
if (Test-Path $vsCodeExecutablePath) {
|
||||
Write-Host "VS Code is already installed."
|
||||
} else {
|
||||
# Download the installer to the Temp directory
|
||||
$vsCodeInstallerFilePath = "$env:TEMP\VSCodeSetup.exe"
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $vsCodeToolDetails.mirrors -outfile $vsCodeInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download VS Code. Please try again later or install manually."
|
||||
} else {
|
||||
# Execute the installer silently with elevated permissions
|
||||
Start-Process -FilePath $vsCodeInstallerFilePath -ArgumentList "/VERYSILENT", "/mergetasks=!runcode" -Verb RunAs -Wait
|
||||
|
||||
# Remove the installer file after installation
|
||||
Remove-Item -Path $vsCodeInstallerFilePath
|
||||
|
||||
# Set alias
|
||||
$setAliasExpression = "Set-Alias -Name $vsCodeAlias -Value `"$vsCodeExecutablePath`""
|
||||
Add-Content -Path $PROFILE -Value $setAliasExpression
|
||||
Invoke-Expression $setAliasExpression
|
||||
|
||||
# Add VS Code to the system PATH environment variable
|
||||
Add-ToEnvPath -NewPath "C:\Users\$env:USERNAME\AppData\Local\Programs\Microsoft VS Code\bin"
|
||||
|
||||
# Disable Visual Studio Code Auto Updates
|
||||
$vsCodeSettingsPath = "${env:APPDATA}\Code\User\settings.json"
|
||||
if (-not (Test-Path $vsCodeSettingsPath)) {
|
||||
# Create the directory if it doesn't exist
|
||||
$dirPath = Split-Path -Path $vsCodeSettingsPath -Parent
|
||||
if (-not (Test-Path $dirPath)) {
|
||||
New-Item -ItemType Directory -Path $dirPath -Force
|
||||
}
|
||||
# Initialize an empty hashtable to act as the JSON object
|
||||
$settingsObj = @{}
|
||||
$settingsObj["update.mode"] = "none" # Set update mode to none
|
||||
$settingsObj | ConvertTo-Json | Set-Content $vsCodeSettingsPath
|
||||
} else {
|
||||
# If the file exists, modify it
|
||||
$settingsObj = Get-Content $vsCodeSettingsPath | ConvertFrom-Json
|
||||
$settingsObj["update.mode"] = "none"
|
||||
$settingsObj | ConvertTo-Json | Set-Content $vsCodeSettingsPath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# - Thunderbird
|
||||
$thunderbirdToolName = "Thunderbird"
|
||||
$thunderbirdToolDetails = Get-ToolDetails -toolsList $toolsList -toolName $thunderbirdToolName
|
||||
$thunderbirdAlias = $thunderbirdToolDetails.alias
|
||||
$thunderbirdExecutablePath = "C:\Program Files\Mozilla Thunderbird\thunderbird.exe"
|
||||
|
||||
# Check if Thunderbird is already installed by checking the Thunderbird executable path
|
||||
if (Test-Path $thunderbirdExecutablePath) {
|
||||
Write-Host "Thunderbird is already installed."
|
||||
} else {
|
||||
# Download the installer to the Temp directory
|
||||
$thunderbirdInstallerFilePath = "$env:TEMP\ThunderbirdSetup.exe"
|
||||
$downloadResult = Invoke-DownloadFileFromAvailableMirrors -mirrorUrls $thunderbirdToolDetails.mirrors -outfile $thunderbirdInstallerFilePath
|
||||
if (-not $downloadResult) {
|
||||
Write-Host "Failed to download Thunderbird. Please try again later or install manually."
|
||||
} else {
|
||||
# Execute the installer silently with elevated permissions
|
||||
Start-Process -FilePath $thunderbirdInstallerFilePath -ArgumentList "/S" -Verb RunAs -Wait
|
||||
|
||||
# Remove the installer file after installation
|
||||
Remove-Item -Path $thunderbirdInstallerFilePath
|
||||
|
||||
# Set alias
|
||||
$setAliasExpression = "Set-Alias -Name $thunderbirdAlias -Value `"$thunderbirdExecutablePath`""
|
||||
Add-Content -Path $PROFILE -Value $setAliasExpression
|
||||
Invoke-Expression $setAliasExpression
|
||||
|
||||
# Add Thunderbird to the system PATH environment variable
|
||||
Add-ToEnvPath -NewPath "C:\Program Files\Mozilla Thunderbird"
|
||||
}
|
||||
}
|
||||
|
||||
# - Server Setup
|
||||
|
||||
$pythonServerPort = 5000
|
||||
$onLogonTaskName = "Server_OnLogon"
|
||||
$requirementsFile = "$scriptFolder\server\requirements.txt"
|
||||
|
||||
# Ensure pip is updated to the latest version
|
||||
Install-PythonPackages -Package "pip" -Arguments "--upgrade"
|
||||
|
||||
Install-PythonPackages -Package "wheel"
|
||||
Install-PythonPackages -Package "pywinauto"
|
||||
|
||||
# Install Python packages from requirements.txt using Python's pip module
|
||||
if (Test-Path $requirementsFile) {
|
||||
Write-Host "Installing required Python packages using pip from requirements file..."
|
||||
Install-PythonPackages -RequirementsPath $requirementsFile
|
||||
} else {
|
||||
Write-Error "Requirements file not found: $requirementsFile"
|
||||
exit
|
||||
}
|
||||
|
||||
# Add a firewall rule to allow incoming connections on the specified port for the Python executable
|
||||
$pythonServerRuleName = "PythonHTTPServer-$pythonServerPort"
|
||||
if (-not (Get-NetFirewallRule -Name $pythonServerRuleName -ErrorAction SilentlyContinue)) {
|
||||
New-NetFirewallRule -DisplayName $pythonServerRuleName -Direction Inbound -Program $pythonExecutablePath -Protocol TCP -LocalPort $pythonServerPort -Action Allow -Profile Any
|
||||
Write-Host "Firewall rule added to allow traffic on port $pythonServerPort for Python"
|
||||
} else {
|
||||
Write-Host "Firewall rule already exists. $pythonServerRuleName "
|
||||
}
|
||||
|
||||
$onLogonScriptPath = "$scriptFolder\on-logon.ps1"
|
||||
# Check if the scheduled task exists before unregistering it
|
||||
if (Get-ScheduledTask -TaskName $onLogonTaskName -ErrorAction SilentlyContinue) {
|
||||
Write-Host "Scheduled task $onLogonTaskName already exists."
|
||||
} else {
|
||||
Write-Host "Registering new task $onLogonTaskName..."
|
||||
Register-LogonTask -TaskName $onLogonTaskName -ScriptPath $onLogonScriptPath -LocalUser "Docker"
|
||||
}
|
||||
|
||||
Start-Sleep -Seconds 10
|
||||
Start-ScheduledTask -TaskName $onLogonTaskName
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"Python": {
|
||||
"mirrors": [
|
||||
"https://www.python.org/ftp/python/3.10.0/python-3.10.0-amd64.exe"
|
||||
],
|
||||
"alias": "python"
|
||||
},
|
||||
"git": {
|
||||
"mirrors": [
|
||||
"https://github.com/git-for-windows/git/releases/download/v2.37.1.windows.1/Git-2.37.1-64-bit.exe"
|
||||
]
|
||||
},
|
||||
"7zip": {
|
||||
"mirrors": [
|
||||
"https://www.7-zip.org/a/7z2407-x64.exe"
|
||||
]
|
||||
},
|
||||
"ffmpeg": {
|
||||
"mirrors": [
|
||||
"https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.7z"
|
||||
]
|
||||
},
|
||||
"Google Chrome": {
|
||||
"mirrors": [
|
||||
"https://dl.google.com/chrome/install/latest/chrome_installer.exe"
|
||||
],
|
||||
"alias": "google-chrome"
|
||||
},
|
||||
"LibreOffice": {
|
||||
"mirrors": [
|
||||
"https://mirror.raiolanetworks.com/tdf/libreoffice/stable/24.8.4/win/x86_64/LibreOffice_24.8.4_Win_x86-64.msi",
|
||||
"https://mirrors.iu13.net/tdf/libreoffice/stable/24.8.4/win/x86_64/LibreOffice_24.8.4_Win_x86-64.msi",
|
||||
"https://download.documentfoundation.org/libreoffice/stable/24.8.4/win/x86_64/LibreOffice_24.8.4_Win_x86-64.msi"
|
||||
]
|
||||
},
|
||||
"VLC": {
|
||||
"mirrors": [
|
||||
"https://ftp.free.org/mirrors/videolan/vlc/3.0.21/win64/vlc-3.0.21-win64.exe",
|
||||
"https://mirror.fcix.net/videolan-ftp/vlc/3.0.21/win64/vlc-3.0.21-win64.exe",
|
||||
"https://mirror.raiolanetworks.com/videolan/vlc/3.0.21/win64/vlc-3.0.21-win64.exe"
|
||||
],
|
||||
"alias": "vlc"
|
||||
},
|
||||
"GIMP": {
|
||||
"mirrors": [
|
||||
"https://www-ftp.lip6.fr/pub/gimp/gimp/v2.10/windows/gimp-2.10.38-setup.exe",
|
||||
"https://download.gimp.org/gimp/v2.10/windows/gimp-2.10.38-setup.exe",
|
||||
"https://www-ftp.lip6.fr/pub/gimp/gimp/v2.10/windows/gimp-2.10.0-setup.exe"
|
||||
],
|
||||
"alias": "gimp"
|
||||
},
|
||||
"VS Code": {
|
||||
"mirrors": [
|
||||
"https://update.code.visualstudio.com/latest/win32-x64-user/stable"
|
||||
],
|
||||
"alias": "code"
|
||||
},
|
||||
"Thunderbird": {
|
||||
"mirrors": [
|
||||
"https://download-installer.cdn.mozilla.net/pub/thunderbird/releases/115.12.1/win64/en-US/Thunderbird%20Setup%20115.12.1.exe",
|
||||
"https://archive.mozilla.org/pub/thunderbird/releases/115.12.1/win64/en-US/Thunderbird%20Setup%20115.12.1.exe"
|
||||
],
|
||||
"alias": "thunderbird"
|
||||
},
|
||||
"Caddy Proxy": {
|
||||
"mirrors": [
|
||||
"https://caddyserver.com/api/download?os=windows&arch=amd64"
|
||||
],
|
||||
"alias": "caddy"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user