'Command is run before the previous one is finished

Consider the following Dockerfile. It attempts to install Visual Studio Build Tools by downloading, installing, and then deleting the installer in a single RUN command.

FROM mcr.microsoft.com/windows/servercore:ltsc2022

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

RUN Invoke-WebRequest \
        -Uri https://aka.ms/vs/17/release/vs_buildtools.exe \
        -OutFile vs_buildtools.exe; \
    .\vs_buildtools.exe --nocache --norestart --quiet --wait \
        --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 \
        --add Microsoft.VisualStudio.Component.Windows10SDK.19041; \
    Remove-Item -Path vs_buildtools.exe

When building the image, the installer is downloaded and started, and then the installer is attempted deleted before the installation is done! This of course generates an error:

Remove-Item : Cannot remove item C:\vs_buildtools.exe: The process cannot
access the file 'C:\vs_buildtools.exe' because it is being used by another
process.

The build continues after the error, completing the installation.

Why is Remove-Item executed before .\vs_buildtools.exe is done?

If I take Remove-Item out into its own RUN command, it works fine:

RUN Invoke-WebRequest \
        -Uri https://aka.ms/vs/17/release/vs_buildtools.exe \
        -OutFile vs_buildtools.exe; \
    .\vs_buildtools.exe --nocache --norestart --quiet --wait \
        --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 \
        --add Microsoft.VisualStudio.Component.Windows10SDK.19041
RUN Remove-Item -Path vs_buildtools.exe


Solution 1:[1]

A workaround is to use cmd instead of powershell.

Both the following approaches work:

RUN Invoke-WebRequest \
        -Uri https://aka.ms/vs/17/release/vs_buildtools.exe \
        -OutFile vs_buildtools.exe; \
    cmd /c "vs_buildtools.exe --nocache --norestart --quiet --wait \
        --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 \
        --add Microsoft.VisualStudio.Component.Windows10SDK.19041"; \
    Remove-Item -Path vs_buildtools.exe
SHELL ["cmd", "/S", "/C"]
RUN curl -SL https://aka.ms/vs/17/release/vs_buildtools.exe -o vs_buildtools.exe \
    && call vs_buildtools.exe --nocache --norestart --quiet --wait \
        --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 \
        --add Microsoft.VisualStudio.Component.Windows10SDK.19041 \
    && call del /q vs_buildtools.exe
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Magnar Myrtveit