Installing Matlab on a Windows Docker - c#

Trying to install Matlab run time on a docker image along with the project I'm working on, the project is an engine that will run a variety of measurements based on what is given to it, many of these measurements use Matlab. When I run the docker though I get an error that the "MWArray assembly failed to be initialized" or that a matlab dll is missing.
I'm trying to run this in Docker for Windows due to a company requirement, and have been unable to successfully get the DockerFile to recognize the MCR. Below is the code that I've been playing with to get the MCR onto a docker.
FROM mcr.microsoft.com/dotnet/framework/runtime:4.7.2-windowsservercore-ltsc2019
ADD http://ssd.mathworks.com/supportfiles/downloads/R2017b/deployment_files/R2017b/installers/win64/MCR_R2017b_win64_installer.exe C:\\MCR_R2017b_win64_installer.zip
# Line 3: Use PowerShell
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
# Line 4: Unpack ZIP contents to installation folder
RUN Expand-Archive C:\\MCR_R2017b_win64_installer.zip -DestinationPath C:\\MCR_INSTALLER
# Line 5: Run the setup command for a non-interactive installation of MCR
RUN Start-Process C:\MCR_INSTALLER\bin\win64\setup.exe -ArgumentList '-mode silent', '-agreeToLicense yes' -Wait
# Line 6: Remove ZIP and installation folder after setup is complete
RUN Remove-Item -Force -Recurse C:\\MCR_INSTALLER, C:\\MCR_R2017b_win64_installer.zip
WORKDIR /app
COPY /Project/bin/Debug/*.dll ./
COPY /Project/bin/Debug/Project.exe .
ENTRYPOINT ["C:\\app\\Project.exe"]
Edit: I think I've found a working solution, following the idea from the other anwser about the ltsc2019 not working with Matlab 2017b. The below code has worked with 2017b inside a docker.
FROM mcr.microsoft.com/windows:1809

Windows Server 2019 is not supported by MATLAB R2017b, and support for it was not introduced until MATLAB R2019a.
For MATLAB R2017b you’ll need Windows Server 2016.
That’s not to say there may not be other issues as well.

Related

Error while loading dll in Docker Container although it exists in it

I'm trying to run a .Net 4.72 app on Docker. That app executed perfectly on my computer, but when I run it on a Docker container, I receive error while loading librdkafka.dll or its dependencies from C:\temp\source\bin\x64\Debug\librdkafka\x64\librdkafka.dll. Check the directory exists, if not check your deployment process. You can also load the library and its dependencies by yourself before any call to Confluent.Kafka.
I verified it's there using a dir command on that folder
This is how my Dockerfile looks like:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
WORKDIR /source
COPY "./bin/x64/Debug/." "c:/temp/source/bin/x64/Debug/"
RUN powershell.exe dir c:/temp/source/bin/x64/Debug/librdkafka/x64
CMD ["c:/temp/source/bin/x64/Debug/testeh.exe"]
Problem solved after installing the VC++ Runtime
ADD https://download.microsoft.com/download/6/A/A/6AA4EDFF-645B-48C5-81CC-ED5963AEAD48/vc_redist.x64.exe /vc_redist.x64.exe
RUN C:\vc_redist.x64.exe /quiet /install

using the docfx.console nuget package on linux

At the moment I have a visual studio project and I use the docfx.console nuget package to build the documentation, and everything works fine and as expected... on windows. The point is now I want to make a docker image based on mcr.microsoft.com/dotnet/core/sdk:3.1 which is based on a linux image. And compiling in this docker image running the command:
dotnet publish -c Release -o out
Gives the following error
> [build 9/9] RUN dotnet publish -c Release -o out:
#22 1.080 Microsoft (R) Build Engine version 16.0.450+ga8dc7f1d34 for .NET Core
#22 1.080 Copyright (C) Microsoft Corporation. All rights reserved.
#22 1.080
#22 2.852 Restore completed in 215.94 ms for /app/Documentation/Documentation.csproj.
#22 6.299 Documentation -> /app/Documentation/bin/Release/netcoreapp2.1/Documentation.dll
#22 6.402 /bin/sh: 2: /tmp/tmpbd72ebbe5e6b49c1b3244f1f50c8b57a.exec.cmd: /root/.nuget/packages/docfx.console/2.48.1/build/../tools/docfx.exe: Exec format error
#22 6.407 /root/.nuget/packages/docfx.console/2.48.1/build/docfx.console.targets(57,5): error MSB3073: The command ""/root/.nuget/packages/docfx.console/2.48.1/build/../tools/docfx.exe" "/app/Documentation/docfx.json" -o "" -l "log.txt" --logLevel "Verbose"" exited with code 2. [/app/Documentation/Documentation.csproj]
I already did some prodding around and I believe I have the issue mostly solved. Running file on console.exe shows that this is a PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows. And these kind of files should not be executed on linux using sh but with mono. And indeed running:
mono docfx.exe "/app/Documentation/docfx.json" -o "" -l "log.txt" --logLevel "Verbose"
builds the documentation just fine as expected. At this point of course I have a bunch of workarounds to get the documentation building correctly, just remove docfx.console form the csproj and build it manualy from the command line using a docker command.
But the question is, can I also use the nuget package on linux by changing how the docfx.exe command is run by the nuget package? Or is this only possible by actually fixing this in docfx.console?
p.s. in case it matters, the version of docfx.console that I am using is the most recent one available at the time of writing, namely 2.48.1
But the question is, can I also use the nuget package on linux by changing how the docfx.exe command is run by the nuget package? Or is this only possible by actually fixing this in docfx.console?
Create script docfx that runs docfx.exe using Mono, e.g., like this (assuming docfx.exe is located in /opt/docfx/docfx.exe):
echo '#!/bin/bash\nmono /opt/docfx/docfx.exe $#' > /usr/bin/docfx && chmod +x /usr/bin/docfx
Then, pass MSBuild parameter BuildDocToolPath with path to that script, e.g., like this:
dotnet publish -c Release -o out -p:BuildDocToolPath=/usr/bin/docfx
docfx.console will than use this path to execute DocFX. I think the property BuildDocToolPath isn't documented anywhere, but you can see it in source code.

DllImport not working on Docker - DllNotFoundException

I have a project developed with .NET Core and C#, running on Docker, that has to call a few functions on a DLL developed with C++.
The problem is: when I run my project without Docker, on Windows using Visual Code, the code runs smoothly, but when I run on Docker, on a Linux container, the code throws an error when trying to execute the DLL function.
I already tried copying the .dll file to the /lib folder, changing it to the parent folder of the project and none of that worked. I started to doubt that the problem is that the file is not found and, by doing some research, I saw that it could be related to the file permissions, so I ran chmod a+wrx on the .dll file, also no success.
This is my Dockerfile configuration:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 80
RUN apt-get update \
&& apt-get install -y --allow-unauthenticated \
libc6-dev \
libgdiplus \
libx11-dev \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& apt-get install -y poppler-utils
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app
COPY . .
RUN dotnet restore --configfile Nuget.config -nowarn:msb3202,nu1503
RUN dotnet publish -c Release -o ./out
FROM base AS final
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "MdeGateway.dll"]
This is the code that tries to access the DLL function:
[DllImport("MyDll.dll")]
private static extern int dllfunction(Int32 argc, IntPtr[] argv);
public static void CallDll(string[] args)
{
IntPtr[] argv = ArrayToArgs(args);
dllfunction(args.Length, argv);
FreeMemory(args, argv);
}
The error occurs when the line 'dllfunction(args.Length, argv);' is executed.
The exact message is:
"Unable to load shared library 'MyDll.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libMyDll.dll: cannot open shared object file: No such file or directory"
Also, if someone can teach me how to set the LD_DEBUG environment variable I would appreciate it.
I have a project developed with .NET Core and C#, running on Docker, that has to call a few functions on a DLL developed with C++. The problem is: when I run my project without Docker, on Windows using Visual Code, the code runs smoothly, but when I run on Docker, on a Linux container, the code throws an error when trying to execute the DLL function.
If I am reading this right, you have a C++ application that you compiled to a .dll (on Windows). You can DllImport this .dll on Windows, but not on Linux (container). Is that right?
Are you aware that C++ code compiled into a .dll (shared library) is a Windows-specific thing? Unmanaged code is architecture and platform specific. An unmanaged .dll compiled on x64 won't run on arm64. A unmanaged .dll compiled on Windows wont run on Linux.
Linux (and Linux containers, such as in docker) can't use a .dll built from unmanaged code on Windows. Linux needs the unmanaged (C++) code to be compiled into a shared library (.so file) for DllImport (and the underlying dlopen calls) to work on Linux. Ideally on the same platform as the container it will be running in.
The mono docs cover an (one particular) implementation of DllImport and give more background on how this works on Linux:
https://www.mono-project.com/docs/advanced/pinvoke/
(But keep in mind that Mono != .NET Core. It should still give you some more background information.)
This does not give the solution to OP's problem, but helps answer his 2nd question
Also, if someone can teach me how to set the LD_DEBUG environment variable I would appreciate it.
I am facing a similar issue, and am also struggling to understand what to do with this LD_DEBUG env variable. Turns out that it controls the verbosity of the debugging info for Unix's dynamic linker.
Following the advice here, running LD_DEBUG=help cat in a linux terminal will give you all the valid options for setting LD_DEBUG.
Here's a screenshot of the output of such command:
Additional useful resources:
Linux Apps Debugging Techniques - The Dynamic Linker
Linux LS.SO man page
Quoting from LD.SO man page mentioned above:
LD_DEBUG (since glibc 2.1)
Output verbose debugging information about operation of
the dynamic linker. The content of this variable is one
of more of the following categories, separated by colons,
commas, or (if the value is quoted) spaces:
help Specifying help in the value of this variable does
not run the specified program, and displays a help
message about which categories can be specified in
this environment variable.
all Print all debugging information (except statistics
and unused; see below).
bindings
Display information about which definition each
symbol is bound to.
files Display progress for input file.
libs Display library search paths.
reloc Display relocation processing.
scopes Display scope information.
statistics
Display relocation statistics.
symbols
Display search paths for each symbol look-up.
unused Determine unused DSOs.
versions
Display version dependencies.
Since glibc 2.3.4, LD_DEBUG is ignored in secure-execution
mode, unless the file /etc/suid-debug exists (the content
of the file is irrelevant).

.NetCore for Mac - Publish to Native Mac App/Binary?

I've been searching for quite some time now, and can't seem to find an answer to this problem. Found only two questions/answers on SO and they still don't answer this question (https://stackoverflow.com/search?q=netcore+publish+mac+app).
I'm working with DotNetCore on Mac, using Visual Studio as the IDE. The app is a Console App, not an ASP.Net app, simple "Hello World" app in C#:
...
Console.Writeline("Hello World");
...
So here's the question... To run the app, I know I can use the "dotnet" command to run it. I'm trying to build/publish the app, as you normally would do in Windows by creating an .exe file, but now on Mac by creating a native binary file.
I have found zero documentation on how to do this, and deploy the application as a self contained app that can run independently without having to call the program using the "dotnet" command. Maybe I'm looking in the wrong places but haven't even found anything on Microsoft's documentation, they all point to documentation for building ASP.Net apps on .NetCore.
Any suggestions?
Found the answer by looking at the "dotnet publish" options:
dotnet publish -c Release --self-contained -r osx.10.13-x64
Where --self-contained includes all required libraries, and -r specifies the runtime target.
$ dotnet publish -c Release --self-contained -a x64
Determining projects to restore...
Restored /Users/walshca/code/temp/MutexThrow/MutexThrow.csproj (in 155 ms).
MutexThrow -> /Users/walshca/code/temp/MutexThrow/bin/Release/net6.0/osx-x64/MutexThrow.dll
MutexThrow -> /Users/walshca/code/temp/MutexThrow/bin/Release/net6.0/osx-x64/publish/
dotnet publish docs
Then I run ./bin/Release/net6.0/osx-x64/publish/MutexThrow
This didn't specify the --output cli arg, so you can see in the build output it defaulted to [project_file_folder]/bin/[configuration]/[framework]/[runtime]/publish/
(In dotnet 6.0 instead of -r runtime target, you can specify --arch x86 and it uses the default RID for your system.)
If your project props sets a different build output, can you find the executable by enumerating files by unix file permissions:
$ gci -r -file | ? UnixMode -match 'x$' | % FullName
/Users/walshca/code/temp/MutexThrow/obj/Release/net6.0/osx-x64/apphost
/Users/walshca/code/temp/MutexThrow/bin/Release/net6.0/osx-x64/MutexThrow
/Users/walshca/code/temp/MutexThrow/bin/Release/net6.0/osx-x64/publish/MutexThrow

Install .NET Framework 3.5 on Windows Server Core Docker

I am struggling to install .NET Framework 3.5 on docker container. I have 4.5 installed already, but need 3.5 to run one Service. Here is my Dockerfile:
FROM microsoft/windowsservercore
SHELL ["powershell"]
RUN Install-WindowsFeature NET-Framework-45-ASPNET ; \
Install-WindowsFeature Web-Asp-Net45
RUN dism /online /enable-feature /featurename:NetFX3 /all
COPY Startup Startup
COPY Service Service
RUN "C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe" WCS.WindowsService.exe
RUN mkdir Temp\Logs
ENTRYPOINT C:\Startup\setupBatch.bat
COPY ContainerApi ContainerApi
RUN Remove-WebSite -Name 'Default Web Site'
RUN New-Website -Name 'ContainerApi' -Port 80 \
-PhysicalPath 'C:\ContainerApi' -ApplicationPool '.NET v4.5'
EXPOSE 80
CMD ["ping", "-t", "localhost"]
When I try to build this, it gives me error on line RUN dism
Error: 0x800f081f
The source files could not be found.
Use the "Source" option to specify the location of the files that are required to restore the feature. For more information on specifying a source location, see http://go.microsoft.com/fwlink/?LinkId=243077.
Now, even if I run dism /online /enable-feature /featurename:NetFX3 /all inside the docker (docker exec) it will still give me the same error.
Anyone with any help?
I took the following steps to resolve this issue:
Got hold of the Windows Server 2016 Core ISO file. Mounted the file on local computer.
Extracted the {mount}:/sources/sxs folder into a zip file (sxs.zip). Ensure that the .NET Framework 3.5 cab file (microsoft-windows-netfx3-ondemand-package.cab) is present in the sxs folder. In my case, this was the only file present in the sxs folder.
Copy the sxs.zip file to my container. I copied it using the dockerfile of the image.
Unzip the file to C:\sources\sxs folder in the container.
Used the Install-WindowsFeature powershell command to install the feature.
Install-WindowsFeature -Name NET-Framework-Features -Source C:\sources\sxs -Verbose
Hope this helps. I also found the following blog useful in understanding the on-demand features.
https://blogs.technet.microsoft.com/askcore/2012/05/14/windows-8-and-net-framework-3-5/
For those who are still are in need of .Net3.5 and .Net4.X (4.7.2 for my case) version in one image.
Please note that MSFT is aware of this demand, and have a base image for this scenario.
Use FROM mcr.microsoft.com/dotnet/framework/sdk:3.5-20191008-windowsservercore-ltsc2019 in your dockerfile.
Saved me all the installation hassles.

Categories

Resources