Этот вопрос занял у меня один день, на самом деле я просто подумал, что сначала все просто.
У меня есть хост-компьютер (Windows 10) с установленным рабочим столом Docker для Windows.
С хост-машины я хотел бы использовать docker run
для запуска контейнера, который содержит простой код для запуска.
Вот код (встроенный в контейнер), это основное консольное приложение .NET (предположим, его встроенное имя console.dll
):
static void Main(string[] args)
{
Console.WriteLine("Running...");
_execTest();
Console.WriteLine("Finished!");
Console.ReadLine();
}
static void _execTest()
{
var sharedFilePath = Path.Combine(Environment.CurrentDirectory, "Temp", "test.exe");
var si = new ProcessStartInfo(sharedFilePath);
si.RedirectStandardOutput = false;
si.RedirectStandardError = false;
si.RedirectStandardInput = false;
Console.WriteLine("Starting ..." + sharedFilePath);
var p = Process.Start(si);
p.WaitForExit();
}
Основной код - просто запустить другую программу с именем test.exe
. Эта программа помещается в общую папку Temp
(которая устанавливается во время вызова docker run
путем монтирования папок между хост-машиной и контейнером).
Вот код для test.exe
(это просто консольное приложение .NET):
static void Main(string[] args)
{
Console.WriteLine("Something went wrong!");
Console.Write("Welldone!");
}
Поэтому я ожидаю, что все сообщения, написанные в test.exe
с использованием Console
, должны быть направлены обратно в родительский контекст (который должен использовать один и тот же STDOUT).
Я проверил код, запустив код для контейнера напрямую, используя dotnet console.dll
, и я могу видеть сообщения (от test.exe
), напечатанные ожидаемым образом.
Однако после развертывания console.dll
на образе (console
) и попробуйте следующую команду для запуска контейнера:
docker run --rm -v D:\SourceFolder:C:\app\Temp console
Тогда сообщения (от test.exe
) не распечатываются. Печатаются только сообщения, написанные непосредственно в родительском контексте (Running...
, Starting...
и Finished!
).
Вы видите, что в приведенной выше команде используется -v
для монтирования папки C:\app\Temp
в контейнере в исходную папку D:\SourceFolder
на хост-компьютере.
И test.exe
помещается в D:\SourceFolder
.
Я уверен, что код контейнера может получить доступ к этому файлу через общую папку.
Это так странно и трудно диагностировать.
Без обмена сообщениями между контейнером и хостом, запуск подобной докер просто бесполезен.
Я надеюсь, что кто-то здесь может дать мне какое-то предложение, чтобы я мог попытаться разобраться в этом. Спасибо!
UPDATE :
Если я использую cmd.exe
(который уже существует в образе докера) с аргументом /?
, то я могу увидеть его вывод. Похоже, что это проблема запуска EXE через папку .
Однако я попытался сначала скопировать общий файл в некоторую локальную папку контейнера и запустить этот файл, но проблема все еще та же. Похоже, это может быть проблема самого файла test.exe
? так смешно.
ОБНОВЛЕНИЕ : спасибо @jazzdelightsme за его полезное предложение о проверке ExitCode
, так что на самом деле в среде контейнера есть что-то, что не может правильно запустить test.exe
. Я попытался скомпилировать test.exe
для самой низкой версии .NET Framework версии 2.0, но все еще с той же ошибкой. Вот содержимое Dockerfile
, которое должно предоставить некоторую информацию о среде контейнера:
FROM microsoft/dotnet:2.1-runtime-nanoserver-1709 AS base
WORKDIR /app
FROM microsoft/dotnet:2.1-sdk-nanoserver-1709 AS build
WORKDIR /src
COPY ConsoleApp/ConsoleApp.csproj ConsoleApp/
RUN dotnet restore ConsoleApp/ConsoleApp.csproj
COPY . .
WORKDIR /src/ConsoleApp
RUN dotnet build ConsoleApp.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish ConsoleApp.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "ConsoleApp.dll"]