Docker容器启动System.Diagnostics.Process时提示文件不存在的问题
问题原因及解决方法
核心原因是你使用的mcr.microsoft.com/dotnet/aspnet:8.0是Linux容器镜像,而CTBot.exe是Windows平台的可执行文件(PE格式),Linux系统无法直接识别并运行这类文件——报错提示的“找不到文件或目录”并非文件不存在,而是系统无法处理该格式的可执行文件。
方案1:生成Linux兼容的CTBot可执行文件
如果CTBot是.NET项目,调整发布流程生成Linux平台的可执行文件,具体步骤如下:
修改Dockerfile,添加CTBot的Linux发布步骤
在build阶段新增CTBot的发布命令,指定Linux运行时标识符(RID):
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /ct.mediator.src COPY ["Mediator/CTMediator.csproj", "Mediator/"] COPY ["Shared/CTShared.csproj", "Shared/"] COPY ["Bot/CTBot.csproj", "Bot/"] # 新增:还原Bot项目依赖 RUN dotnet restore "./Bot/CTBot.csproj" RUN dotnet restore "./Mediator/CTMediator.csproj" COPY . . WORKDIR "/ct.mediator.src/Mediator" RUN dotnet build "./CTMediator.csproj" -c $BUILD_CONFIGURATION -o /ct.mediator.app/build # 新增:发布CTBot为Linux可执行文件(--self-contained=false表示依赖系统.NET Runtime) WORKDIR "/ct.mediator.src/Bot" RUN dotnet publish "./CTBot.csproj" -c $BUILD_CONFIGURATION -o /ct.mediator.app/bot-publish -r linux-x64 --self-contained false FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish "./CTMediator.csproj" -c $BUILD_CONFIGURATION -o /ct.mediator.app/publish /p:UseAppHost=false FROM base AS final WORKDIR /ct.mediator.app COPY --from=publish /ct.mediator.app/publish . # 修改:复制Linux可执行文件,而非Windows的.exe COPY --from=build /ct.mediator.app/bot-publish/CTBot /ct.mediator.app/CTBot ENTRYPOINT ["dotnet", "CTMediator.dll"]
修改启动代码
将Process启动路径改为Linux可执行文件名(不带.exe后缀):
var process = new Process() { StartInfo = new("/ct.mediator.app/CTBot", "argument1", "argument2") { WindowStyle = ProcessWindowStyle.Hidden, RedirectStandardOutput = true } }; process.Start();
方案2:改用Windows容器镜像
如果必须保留CTBot.exe的Windows格式,将容器基础镜像替换为Windows版本的.NET镜像:
修改Dockerfile的基础镜像
# 使用Windows Nano Server的ASP.NET镜像 FROM mcr.microsoft.com/dotnet/aspnet:8.0-nanoserver-20H2 AS base WORKDIR C:\ct.mediator.app EXPOSE 5212 EXPOSE 7195 # 对应使用Windows版本的SDK镜像 FROM mcr.microsoft.com/dotnet/sdk:8.0-nanoserver-20H2 AS build ARG BUILD_CONFIGURATION=Release WORKDIR C:\ct.mediator.src COPY ["Mediator/CTMediator.csproj", "Mediator/"] COPY ["Shared/CTShared.csproj", "Shared/"] COPY ["Bot/CTBot.csproj", "Bot/"] RUN dotnet restore ".\Mediator\CTMediator.csproj" COPY . . WORKDIR "C:\ct.mediator.src\Mediator" RUN dotnet build ".\CTMediator.csproj" -c $BUILD_CONFIGURATION -o C:\ct.mediator.app\build FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish ".\CTMediator.csproj" -c $BUILD_CONFIGURATION -o C:\ct.mediator.app\publish /p:UseAppHost=false FROM base AS final WORKDIR C:\ct.mediator.app COPY --from=publish C:\ct.mediator.app\publish . COPY --from=build C:\ct.mediator.src\Bot\bin\Release\net8.0\CTBot.exe C:\ct.mediator.app\CTBot.exe ENTRYPOINT ["dotnet", "CTMediator.dll"]
修改启动代码的路径格式
使用Windows风格的路径:
var process = new Process() { StartInfo = new(@"C:\ct.mediator.app\CTBot.exe", "argument1", "argument2") { WindowStyle = ProcessWindowStyle.Hidden, RedirectStandardOutput = true } }; process.Start();
验证方法
进入容器执行以下命令,确认文件格式:
# 针对Linux容器 file /ct.mediator.app/CTBot.exe # 若输出类似 "PE32+ executable (console) x86-64, for MS Windows",说明是Windows格式;若为"ELF 64-bit LSB executable"则是Linux格式
内容的提问来源于stack exchange,提问作者Sylas Coker
相关产品推荐
相关产品推荐

