The system cannot find the file specified when trying to run vc_redist.x64 within nanoserver build using dockerfile - c++

I am trying to setup a nanoserver container in order to run a C++ executable that was built with the /MD flag in Visual Studio 2017.
I know I need to install Microsoft Visual C++ Redistributable for Visual Studio 2017.
I managed to create the container, download the Redistributable and add it to the container at the root. however when build from the Dockerfile I get the following error message:
Exception(2) tid(360) 80070002 The system cannot find the file specified.
CallContext:[\Bridge_ProcessMessage\ComputeSystemManager_ExecuteProcess\VmHostedContainer_ExecuteProcess]
Provider: 00000000-0000-0000-0000-000000000000] extra info: {"CommandLine":"powershell -Command $ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; $verbosePreference='Continue'; Start-Process -filepath c:\\vc_redist.exe -ArgumentList \"/install\", \"/passive\", \"/norestart\", \"'/log a.txt'\" -PassThru | wait-process","User":"ContainerUser","WorkingDirectory":"C:\\","Environment":{"PSCORE":"C:\\Program Files\\PowerShell\\pwsh.exe","ProgramFiles":"C:\\Program Files","VS2017":"https://aka.ms/vs/16/release/vc_redist.x64.exe"},"CreateStdInPipe":true,"CreateStdOutPipe":true,"CreateStdErrPipe":true,"ConsoleSize":[0,0]}
here is my Dockerfile:
ARG FROM_IMAGE=microsoft/powershell:6.0.0-beta.9-nanoserver-1709
FROM ${FROM_IMAGE}
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; $verbosePreference='Continue';"]
ARG VS2017=https://aka.ms/vs/16/release/vc_redist.x64.exe
ADD ${VS2017} /vc_redist.exe
RUN Start-Process -filepath c:\vc_redist.exe -ArgumentList "/install", "/passive", "/norestart", "'/log a.txt'" -PassThru | wait-process
I tried removing last line from dockerfile and running it within the container after building I simply get no output.
also would like to avoid using windows server core as we are trying to keep the size as small as possible.
Any help greatly appreciated.

Related

AWS PowerShell EventBridge assembly model not found

Error:
New-Object : Cannot find type [PutEventsRequestEntry]: verify that the
assembly containing this type is loaded
Code:
$entry = New-Object -Type Amazon.EventBridge.Model.PutEventsRequestEntry
$entry.Detail = $detailObject
$entry.Source = "inbound"
$entry.DetailType = "record sent"
$entry.Time = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
Write-EVBEvent -Entry $events -Select "*"
I have AWS.Tools.Common and AWS.Tools.EventBridge modules installed via this command:
Install-Module -Name AWS.Tools.EventBridge
And I can see them listed with this command:
Get-Module -ListAvailable
This code was originally working, I'm not sure what has changed. It's on a WorkSpaces instance though, so anything might have happened.
Do I need to Install the AWS SDK as well?
https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EventBridge/TPutEventsRequestEntry.html
I tried to install like this:
Install-Package AWSSDK.EventBridge -Version 3.7.5.29
No match was found for the specified search criteria and package name
'AWSSDK.EventBridge'
I tried installing the assembly like this:
Download SDK from here: https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-obtain-assemblies.html
Move the AWSSDK.EventBridge.dll and AWSSDK.Core.dll files to the script root, and unblock the file in properties.
Load the library:
Add-Type -LiteralPath "./AWSSDK.Core.dll"
Add-Type -LiteralPath "./AWSSDK.EventBridge.dll"
But I still get the same error related to the PutEventsRequestEntry object.
Edit:
I removed all associated libraries, and reinstalled using this command:
Install-Module -Name AWS.Tools.Installer
Install-AWSToolsModule -Name EventBridge -CleanUp
No change though.
This is a known issue with AWS PowerShell tools and PowerShell 5, with no clear resolution, other than upgrading to PowerShell 7, or continually reinstalling until it works...
The issue self-resolves by itself after multiple retries to install a
module.
Even under PS7 I still had issues, and need to run this command also:
Import-Module AWS.Tools.EventBridge
Some details here:
https://github.com/aws/aws-tools-for-powershell/issues/273

Docker image for building solution with both C++ and C# projects

I had a docker file that used to successfully build a VS2019 solution containing C++ and C# projects. Then recently it stopped working.
I've been investigating and trying various combinations of docker images, without success.
I've now got a test VS2019 solution with one C++ hello world console project and one C# .NET5 hello world console project. This does not compile using the following docker file:
e# escape=`
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8
SHELL ["cmd", "/S", "/C"]
# Copy our Install script.
COPY Install.cmd C:\TEMP\
# Download collect.exe in case of an install failure.
ADD https://aka.ms/vscollect.exe C:\TEMP\collect.exe
ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:\Temp\vs_buildtools.exe
ADD https://aka.ms/vs/16/release/channel C:\Temp\VisualStudio.chman
RUN C:\Temp\vs_buildtools.exe `
--quiet --wait --norestart --nocache `
--installPath C:\BuildTools `
--channelUri C:\Temp\VisualStudio.chman `
--installChannelUri C:\Temp\VisualStudio.chman `
--add Microsoft.VisualStudio.Workload.VCTools;includeRecommended `
--add Microsoft.Component.MSBuild `
|| IF "%ERRORLEVEL%"=="3010" EXIT 0
WORKDIR /src
ENTRYPOINT ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"] && CMD "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Commom7\Tools\VsDevCmd.bat"
The compiler error is
C:\src\dockertest\ConsoleApplications\ConsoleApplicationCpp\ConsoleApplicationCpp.vcxproj(28,3): error MSB4019: The imp
orted project "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.Cpp.D
efault.props" was not found. Confirm that the expression in the Import declaration "C:\Program Files (x86)\Microsoft Vi
sual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.Cpp.Default.props" is correct, and that the file exist
s on disk.
Interestingly, this installs MSBuild for VS2022, despite the aka.ms/vs/16 link requesting VS2019.
Interestingly, this installs .NET SDK 6.0.101, despite the FROM line asking for 4.8
But the main problem is the VC tools are not installed. The folder C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft does not contain the VC folder.
I've followed various examples but they don't appear to work any more with the recent docker images.
Try this:
# escape=`
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8
SHELL ["cmd", "/S", "/C"]
ADD https://aka.ms/vs/17/release/vs_buildtools.exe C:\vs_buildtools.exe
RUN C:\vs_buildtools.exe `
--quiet --wait --norestart --nocache modify `
--installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\BuildTools" `
--add Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools;includeRecommended `
--add Microsoft.VisualStudio.Workload.MSBuildTools;includeRecommended `
--add Microsoft.VisualStudio.Workload.VCTools;includeRecommended `
|| IF "%ERRORLEVEL%"=="3010" EXIT 0
RUN del C:\vs_buildtools.exe
COPY . .
RUN nuget restore
RUN MSBuild GameClient.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64
WORKDIR /Product
ENTRYPOINT ["C:\\Product\\WOTS.exe", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]

Use Docker-Windows for Gitlab-runner

I'm trying to use Docker in Windows to create a Gitlab-Runner to build a C++ application. It works so far, but I guess there are better aproaches. Here's what I did:
Here's my initial Docker Container:
FROM mcr.microsoft.com/windows/servercore:2004
# Restore the default Windows shell for correct batch processing.
SHELL ["cmd", "/S", "/C"]
# Download the Build Tools bootstrapper.
ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe
# Install Build Tools with the Microsoft.VisualStudio.Workload.AzureBuildTools workload, excluding workloads and components with known issues.
RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
--installPath C:\BuildTools `
--add Microsoft.VisualStudio.Workload.VCTools `
--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
--add Microsoft.VisualStudio.Component.VC.CMake.Project `
--add Microsoft.VisualStudio.Component.Windows10SDK.19041 `
--locale en-US `
|| IF "%ERRORLEVEL%"=="3010" EXIT 0
# Define the entry point for the docker container.
# This entry point starts the developer command prompt and launches the PowerShell shell.
ENTRYPOINT ["cmd","/k", "C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
And my .gitlab-ci.yml looks like this:
build Docker Windows:
image: buildtools2019_core
stage: build
tags:
- win-docker
script:
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Release -DenableWarnings=ON -G Ninja -DCMAKE_MAKE_PROGRAM=Ninja ../
- ninja
This works so far and everthing builds correctly. The main problem however is that if the build fails the job succeeds anyways. I suspect that my entrypoint is wrong because powershell is executed inside of a cmd and only the exit code of cmd is checked which always succeeds.
So I tried to use powershell directly as entrypoint. I need to set environment variables via vcvars64.bat but that is not that trivial to do. I tried to execute the "Developer Powershell for VS 2019" but I can't execute the link in the entrypoint directly and the link looks like this:
"C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -noe -c "&{Import-Module """C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"""; Enter-VsDevShell 6f66c5f6}"
Which I don't quit understand what it does and the hash also varies from installation to installation. Also simply using this as entrypoint didn't work.
I then tried to use the Invoke-Environment Script taken from "https://github.com/nightroman/PowerShelf/blob/master/Invoke-Environment.ps1". This allows me to execute the .bat file from powershell like this:
Invoke-Environment C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat
But to do this I need to add this function to my profile, as far as I understood. I did this by copying it to "C:\Windows\system32\WindowsPowerShell\v1.0\profile.ps1" so that it would be accessible by all users.
In my Docker file I added:
COPY Invoke-Environment.ps1 C:\Windows\system32\WindowsPowerShell\v1.0\profile.ps1
and replaced the entrypoint with:
ENTRYPOINT ["C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", "-NoExit", "-NoLogo", "-ExecutionPolicy", "Bypass", "Invoke-Environment C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat"]
But that didn't initialize the environment variables correctly. Also "Invoke-Environment" is not found by the gitlab-runner. My last resort was to write a small script (Init64.ps1) that executes the Invoke-Environment function with vcvars64.bat:
function Invoke-Environment {
param
(
# Any cmd shell command, normally a configuration batch file.
[Parameter(Mandatory=$true)]
[string] $Command
)
$Command = "`"" + $Command + "`""
cmd /c "$Command > nul 2>&1 && set" | . { process {
if ($_ -match '^([^=]+)=(.*)') {
[System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])
}
}}
}
Invoke-Environment C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat
I copied this in docker via:
COPY Init64.ps1 Init64.ps1
and used this entrypoint:
ENTRYPOINT ["C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe"]
In my build script I need to manually call it to setup the variables:
build Docker Windows:
image: buildtools2019_core
stage: build
tags:
- win-docker
script:
- C:\Init64.ps1
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Release -DenableWarnings=ON -G Ninja -DCMAKE_MAKE_PROGRAM=Ninja ../
- ninja
Now everything works as intended the build works and the job only succeeds if the build succeeds.
However, I would prefer to setup my environment in the entrypoint so that I don't have to do this in my build script.
Is there a better way to do this? Also feel free to suggest any improvements I could make.
Ok, after some struggling, here is my entry.bat that correctly loads the environment exports the error-level/return-value:
REM Load environment
call C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat
REM If there are no parameters call cmd
IF [%1] == [] GOTO NOCALL
REM If there are parameters call cmd with /S for it to exit directly
cmd /S /C "%*"
exit %errorlevel%
:NOCALL
cmd
exit %errorlevel%

MSBuild fails to build Visual Studio Project due to missing property files (potentially IDE related)

I'm trying to get Jenkins running in a docker windows container and I've got most everything set up but I continue to run into a compilation error:
22:21:06 C:\JENKINS_HOME\workspace\iCEWav\src\engine\IceLibrary\IceLibrary.vcxproj(27,3): error MSB4019: The imported project "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Microsoft\VC\v160\Microsoft.Cpp.Default.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
I installed MSBuild using this command:
RUN C:\TEMP\Install.cmd C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
--channelUri C:\TEMP\VisualStudio.chman `
--installChannelUri C:\TEMP\VisualStudio.chman `
--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended`
--remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
--remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
--remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
--remove Microsoft.VisualStudio.Component.Windows81SDK `
--installPath C:\BuildTools
It looks like the Visual Studio Project that I created in Visual Studio Community looks for a properties file here:
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
This builds fine on the local machine where the project was created but the file is missing in the docker container. I'm wondering if these files are generated once the IDE runs the first time or am I missing a step here?
So my boiled down question... Can I compile a Visual Studio Project File using only Visual Studio BuildTools? If so, how do I generate or ignore these property files.
Well that didn't take too long. According to documentation, MSBuild is actually not apart of the recommended or required workload for VCTools. The MSBuild that was already on the Docker container came from the base image provided by Micosoft and lacked the VC tools (mcr.microsoft.com/dotnet/framework/sdk:4.7.2-windowsservercore-ltsc2019).
I modified the install command to include MSBuild which ultimately downloaded the VC directories needed.
RUN C:\TEMP\Install.cmd C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
--channelUri C:\TEMP\VisualStudio.chman `
--installChannelUri C:\TEMP\VisualStudio.chman `
--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended`
--add Microsoft.Component.MSBuild `
--remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
--remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
--remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
--remove Microsoft.VisualStudio.Component.Windows81SDK `
--installPath C:\BuildTools
This installed the necessary files.

Windows container fails to build VS 2013 C++ project with error MSB6006: “midl.exe” exited with code -2147024774

I should be able to build a C++ project on a windows docker container using MSBuild.exe
Command:
C:\'Program Files (x86)'\MSBuild\12.0\Bin\MSBuild.exe .\TestNative.sln /p:Configuration=Release /p:Platform=x64 /m /t:Build /p:ResGenExecuteAsTool=true /toolsversion:12.0
C++ Project fails to build with error:
Midl:
C:\Program Files (x86)\Windows Kits\8.1\bin\x86\midl.exe /W1 /nologo /char signed /env x64 /h “Enumglob.h” /tlb “x64\ReleaseMinDependency\TestNativeCore.tlb” Enumglob.idl
64 bit Processing .\Enumglob.idl
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(1178,5): error MSB6006: “midl.exe” exited with code -2147024774.
....
....
Build FAILED.
Information
This is my Dockerfile which already has the Visual C++ Redistributables installed and the project copied over using Docker cp command. I’m not sure what else is missing and the error message is not helpful.
FROM chemsorly/msbuilder:1.0.0-vsc
SHELL ["powershell"]
# Download VC++ 2010 SP1 Redistributable Package (x64)
RUN Invoke-WebRequest http://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe -OutFile "$env:TEMP\vc2010x64.exe" -UseBasicParsing
RUN Start-Process "$env:TEMP\vc2010x64.exe" '/features + /q' -wait
RUN Remove-Item "$env:TEMP\vc2010x64.exe"
# Download VC++ 2012 Update 4 Redistributable Package (x64)
RUN Invoke-WebRequest http://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe -OutFile "$env:TEMP\vc2012x64.exe" -UseBasicParsing
RUN Start-Process "$env:TEMP\vc2012x64.exe" '/features + /q' -wait
RUN Remove-Item "$env:TEMP\vc2012x64.exe"
# Download VC++ 2013 Redistributable Package (x64)
RUN Invoke-WebRequest http://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe -OutFile "$env:TEMP\vc2013x64.exe" -UseBasicParsing
RUN Start-Process "$env:TEMP\vc2013x64.exe" '/features + /q' -wait
RUN Remove-Item "$env:TEMP\vc2013x64.exe"
# Note: Add MSBuild to path
RUN setx PATH '%PATH%;C:\\Program Files (x86)\\MSBuild\\14.0\\Bin'
# Download VC++ 2015 Build Tools
RUN Invoke-WebRequest 'http://go.microsoft.com/fwlink/?LinkId=691126"&"fixForIE=.exe"&"__hstc=268264337.f43737e851d862336312053b3a368915.1511781465043.1511781465043.1511781465043.1"&"__hssc=268264337.1.1511781465043"&"__hsfp=1781426681' -OutFile "$env:TEMP\vc++2015bt.exe" -UseBasicParsing
RUN Start-Process "$env:TEMP\vc++2015bt.exe" '/features + /q' -wait
Question: I'm not sure what tools I'm missing on my container so what is the above error and how can I resolve it?