Compare commits

..

3 Commits
v2.20 ... v2.22

Author SHA1 Message Date
hellodword
02c95fb960 feat: Automatically execute script after installation (#423) 2024-04-28 13:03:37 +02:00
Kroese
3390ef8101 feat: Disable S3 and S4 standby modes (#434) 2024-04-27 18:46:09 +02:00
Kroese
80ae80ae10 fix: Support read-only images (#432) 2024-04-27 12:05:28 +02:00
21 changed files with 178 additions and 46 deletions

View File

@@ -6,9 +6,7 @@ body:
- type: markdown
attributes:
value: |
Have a general question about Windows for Docker?
Please do not use this form for technical issues.
And make sure to check the [FAQ](https://github.com/dockur/windows/blob/master/readme.md) first!
Please do not use this form for technical issues, and make sure to check the [FAQ](https://github.com/dockur/windows/blob/master/readme.md) first!
- type: textarea
id: question
attributes:

View File

@@ -1,5 +1,5 @@
FROM scratch
COPY --from=qemux/qemu-docker:4.25 / /
COPY --from=qemux/qemu-docker:4.26 / /
ARG DEBCONF_NOWARNINGS "yes"
ARG DEBIAN_FRONTEND "noninteractive"

View File

@@ -462,6 +462,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>23</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>

View File

@@ -470,6 +470,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>23</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>

View File

@@ -468,6 +468,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>23</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>

View File

@@ -464,6 +464,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>23</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>

View File

@@ -485,6 +485,11 @@
<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>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>

View File

@@ -487,6 +487,11 @@
<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>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>

View File

@@ -302,6 +302,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>17</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>

View File

@@ -341,6 +341,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>17</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>

View File

@@ -371,6 +371,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>23</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>

View File

@@ -375,6 +375,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>23</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>

View File

@@ -375,6 +375,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>23</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>

View File

@@ -305,6 +305,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>17</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>

View File

@@ -326,6 +326,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>17</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>

View File

@@ -335,6 +335,11 @@
<CommandLine>netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes</CommandLine>
<Description>Enable File Sharing</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>17</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>

View File

@@ -259,6 +259,11 @@
<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>20</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>

View File

@@ -164,13 +164,11 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
- /home/user/example.iso:/storage/custom.iso
```
Replace the example path `/home/user/example.iso` with the filename of the desired ISO file.
Replace the example path `/home/user/example.iso` with the filename of the desired ISO file. The value of `VERSION` will be ignored in this case.
* ### How do I customize the installation?
You can customize any part of the automatic installation, and even execute certain commands at boot if needed.
Download the XML file corresponding to your Windows version, for example [win11x64.xml](https://raw.githubusercontent.com/dockur/windows/master/assets/win11x64.xml). Then apply your modifications to it, and add this line to your compose file:
You can customize every setting used by the automatic installation. Download the XML file corresponding to your Windows version, for example [win11x64.xml](https://raw.githubusercontent.com/dockur/windows/master/assets/win11x64.xml). Then apply your modifications to it, and add this line to your compose file:
```yaml
volumes:
@@ -179,6 +177,17 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
Replace the example path `/home/user/custom.xml` with the filename of the modified XML file.
* ### How do I run a script after installation?
To run your own script after installation, you can create a file called `install.bat` and place it in a folder together with other files it needs (programs to install for example). Then bind it in your compose file like this:
```yaml
volumes:
- /home/user/example:/storage/oem
```
The example path `/home/user/example` will be copied to `C:\OEM` during installation and the containing `install.bat` will be executed.
* ### How do I perform a manual installation?
It's best to use the automatic installation, as it optimizes various settings for use with this container. These tweaks will give you maximum performance and prevent common issues.

View File

@@ -275,20 +275,25 @@ finishInstall() {
fi
fi
rm -f "$STORAGE/windows.ver"
rm -f "$STORAGE/windows.old"
rm -f "$STORAGE/windows.boot"
rm -f "$STORAGE/windows.mode"
cp /run/version "$STORAGE/windows.ver"
if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
echo "$MACHINE" > "$STORAGE/windows.old"
if [[ "${MACHINE,,}" != "q35" ]]; then
echo "$MACHINE" > "$STORAGE/windows.old"
fi
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
else
rm -f "$STORAGE/windows.old"
fi
# Enable secure boot + TPM on manual installs as Win11 requires
if [[ "$MANUAL" == [Yy1]* ]] || [[ "$aborted" == [Yy1]* ]]; then
if [[ "${DETECTED,,}" == "win11"* ]]; then
BOOT_MODE="windows_secure"
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
# Enable secure boot + TPM on manual installs as Win11 requires
if [[ "$MANUAL" == [Yy1]* ]] || [[ "$aborted" == [Yy1]* ]]; then
if [[ "${DETECTED,,}" == "win11"* ]]; then
BOOT_MODE="windows_secure"
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
fi
fi
fi
@@ -1077,6 +1082,35 @@ updateImage() {
return 0
}
copyOEM() {
local dir="$1"
local folder="$STORAGE/oem"
local src
[ ! -d "$folder" ] && folder="$STORAGE/OEM"
[ ! -d "$folder" ] && folder="$STORAGE/shared/oem"
[ ! -d "$folder" ] && folder="$STORAGE/shared/OEM"
[ ! -d "$folder" ] && return 0
local msg="Copying OEM folder to image..."
info "$msg" && html "$msg"
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
if [ ! -d "$src" ]; then
error "failed to locate 'sources' folder in ISO image!" && return 1
fi
local dest="$src/\$OEM\$/\$1/"
mkdir -p "$dest"
if ! cp -r "$folder" "$dest"; then
error "Failed to copy OEM folder!" && return 1
fi
return 0
}
buildImage() {
local dir="$1"
@@ -1151,16 +1185,22 @@ buildImage() {
bootWindows() {
if [ -f "$STORAGE/windows.old" ]; then
MACHINE=$(<"$STORAGE/windows.old")
[ -z "$MACHINE" ] && MACHINE="q35"
BOOT_MODE="windows_legacy"
if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then
BOOT_MODE=$(<"$STORAGE/windows.mode")
if [ -s "$STORAGE/windows.old" ] && [ -f "$STORAGE/windows.old" ]; then
MACHINE=$(<"$STORAGE/windows.old")
fi
rm -rf "$TMP"
return 0
fi
if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then
BOOT_MODE=$(<"$STORAGE/windows.mode")
# Migrations
if [ -f "$STORAGE/windows.old" ]; then
MACHINE=$(<"$STORAGE/windows.old")
[ -z "$MACHINE" ] && MACHINE="q35"
BOOT_MODE="windows_legacy"
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
rm -rf "$TMP"
return 0
fi
@@ -1231,6 +1271,10 @@ if ! rm -f "$ISO" 2> /dev/null; then
rm -f "$ISO"
fi
if ! copyOEM "$DIR"; then
exit 63
fi
if ! buildImage "$DIR"; then
exit 65
fi

View File

@@ -6,13 +6,14 @@ set -Eeuo pipefail
QEMU_TERM=""
QEMU_PORT=7100
QEMU_TIMEOUT=110
QEMU_PID="/run/shm/qemu.pid"
QEMU_PTY="/run/shm/qemu.pty"
QEMU_LOG="/run/shm/qemu.log"
QEMU_OUT="/run/shm/qemu.out"
QEMU_END="/run/shm/qemu.end"
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 /run/shm/qemu.*
rm -f "$QEMU_DIR/qemu.*"
touch "$QEMU_LOG"
_trap() {
@@ -27,7 +28,7 @@ ready() {
[ -f "$STORAGE/windows.boot" ] && return 0
[ ! -s "$QEMU_PTY" ] && return 1
if [ -f "$STORAGE/windows.old" ]; then
if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
local last
local bios="Booting from Hard"
last=$(grep "^Booting.*" "$QEMU_PTY" | tail -1)
@@ -68,8 +69,9 @@ finish() {
if [ ! -f "$STORAGE/windows.boot" ] && [ -f "$STORAGE/$BASE" ]; then
# Remove CD-ROM ISO after install
if ready; then
rm -f "$STORAGE/$BASE"
touch "$STORAGE/windows.boot"
if rm -f "$STORAGE/$BASE" 2>/dev/null; then
touch "$STORAGE/windows.boot"
fi
fi
fi

View File

@@ -3,22 +3,27 @@ set -Eeuo pipefail
: "${SAMBA:="Y"}"
[[ "$DHCP" == [Yy1]* ]] && return 0
[[ "$SAMBA" != [Yy1]* ]] && return 0
[[ "$NETWORK" != [Yy1]* ]] && return 0
SHARE="$STORAGE/shared"
hostname="host.lan"
interface="dockerbridge"
mkdir -p "$SHARE"
chmod -R 777 "$SHARE"
if [[ "$DHCP" == [Yy1]* ]]; then
hostname="$IP"
interface="$VM_NET_DEV"
fi
SAMBA="/etc/samba/smb.conf"
share="$STORAGE/shared"
mkdir -p "$share"
[ -z "$(ls -A "$share")" ] && chmod -R 777 "$share"
{ echo "[global]"
echo " server string = Dockur"
echo " netbios name = dockur"
echo " netbios name = $hostname"
echo " workgroup = WORKGROUP"
echo " interfaces = dockerbridge"
echo " interfaces = $interface"
echo " bind interfaces only = yes"
echo " security = user"
echo " guest account = nobody"
@@ -32,14 +37,14 @@ SAMBA="/etc/samba/smb.conf"
echo " disable spoolss = yes"
echo ""
echo "[Data]"
echo " path = $SHARE"
echo " path = $share"
echo " comment = Shared"
echo " writable = yes"
echo " guest ok = yes"
echo " guest only = yes"
echo " force user = root"
echo " force group = root"
} > "$SAMBA"
} > "/etc/samba/smb.conf"
{ echo "--------------------------------------------------------"
echo " $APP for Docker v$(</run/version)..."
@@ -59,7 +64,7 @@ SAMBA="/etc/samba/smb.conf"
echo ""
echo "Replace the example path /home/user/example with the desired storage folder."
echo ""
} | unix2dos > "$SHARE/readme.txt"
} | unix2dos > "$share/readme.txt"
! smbd && smbd --debug-stdout
@@ -67,17 +72,16 @@ isXP="N"
if [ -f "$STORAGE/windows.old" ]; then
MT=$(<"$STORAGE/windows.old")
if [[ "${MT,,}" == "pc-q35-2"* ]]; then
isXP="Y"
fi
[[ "${MT,,}" == "pc-q35-2"* ]] && isXP="Y"
fi
if [[ "$isXP" == [Yy1]* ]]; then
[[ "$DHCP" == [Yy1]* ]] && return 0
# Enable NetBIOS on Windows XP
! nmbd && nmbd --debug-stdout
else
# Enable Web Service Discovery
wsdd -i dockerbridge -p -n "host.lan" &
wsdd -i "$interface" -p -n "$hostname" &
fi
return 0