如何使用 Visual Studio 2022 在 docker 中调试 x86 .net7 服务

How to debug an x86 .net7 service in docker with Visual Studio 2022

提问人:João Mendes 提问时间:10/20/2023 更新时间:10/24/2023 访问量:71

问:

我正在构建一个 C# 中间件服务,该服务必须调用 32 位 COM DLL 并调用 SOAP Web 服务。正在针对 编写服务。NET7.0,我正在使用 Visual Studio 2022 社区版。

由于该 DLL,项目必须面向 x86 Windows 平台。

我想将此服务容器化。我安装了最新的 Docker 桌面,并将 Docker 支持添加到项目中。

当我点击调试时,VS 会正确创建容器并下载预期的映像,但是,一旦容器启动并运行,它就会静默退出调试模式,并且调试窗口或容器工具日志都没有输出。

Dockerfile 几乎是 VS 生成的默认文件:

FROM mcr.microsoft.com/dotnet/runtime:7.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["Trayport/Trayport.csproj", "Trayport/"]
RUN dotnet restore "Trayport/Trayport.csproj"
COPY . .
WORKDIR "/src/Trayport"
RUN dotnet build "Trayport.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Trayport.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Trayport.dll"]

下面是 csproj:

<Project Sdk="Microsoft.NET.Sdk.Worker">
  <PropertyGroup>
    <TargetFramework>net7.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UserSecretsId>dotnet-Trayport-69c0cd6b-2a27-4fa8-ab42-df4d743d63e3</UserSecretsId>
    <DockerDefaultTargetOS>Windows</DockerDefaultTargetOS>
    <ServerGarbageCollection>true</ServerGarbageCollection>
    <Platforms>x86</Platforms>
  </PropertyGroup>

  <ItemGroup>
    <COMReference Include="GV8APILib">
      <VersionMinor>0</VersionMinor>
      <VersionMajor>1</VersionMajor>
      <Guid>0a67e301-3ecb-47be-bba9-dc67ff219358</Guid>
      <Lcid>0</Lcid>
      <WrapperTool>tlbimp</WrapperTool>
      <Isolated>false</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
    <PackageReference Include="System.ServiceModel.Duplex" Version="4.10.*" />
    <PackageReference Include="System.ServiceModel.Federation" Version="4.10.*" />
    <PackageReference Include="System.ServiceModel.Http" Version="4.10.*" />
    <PackageReference Include="System.ServiceModel.NetTcp" Version="4.10.*" />
    <PackageReference Include="System.ServiceModel.Security" Version="4.10.*" />
  </ItemGroup>

  <ItemGroup>
    <None Update="Gv8Api.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="trayport-api-schema.xsd">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>

从我在大量谷歌搜索后能够收集到的信息来看,这似乎与以下事实有关:VS docker 构建将 64 位远程调试器部署并运行到容器,但随后尝试附加到 32 位调试器。当它找不到时,它就会停止,没有输出。

话又说回来,问题可能完全出在别处......

如果相关,Docker Desktop 和 VS 在同一台主机上运行,即 64 位 Windows 11 PC。

docker visual-studio 调试 32 位-64 位

评论

0赞 stefan.seeland 10/24/2023
您是否正在尝试调试面向 Linux 容器中窗口的 .net 项目?
0赞 João Mendes 10/24/2023
@stefan.seeland 不,是 Windows

答:

2赞 Nathan Carlson - MSFT 10/24/2023 #1

根据您的 Dockerfile,我相信您有两个问题:

  1. 官方 .NET 运行时映像只有 x64 运行时。
  2. VS 中的容器工具假定为 x64,因此它们仅设置 x64 调试器,并尝试启动 x64 运行时。

第一个问题的快速解决方法是将 x86 运行时复制到现有映像中。下面是更改 Dockerfile 以执行此操作的示例
您可以通过手动指定调试器来解决第二个问题,使用 ,以及要启动的程序。下面是这些属性的文档,以及设置这些属性以支持容器中的 x86 调试的示例。在制作示例时,我需要使用 ServerCore 作为基本映像来运行 x86 运行时,因此我能够使用完整的远程调试器。
ContainerVsDbgPathDockerDebuggeeProgram

评论

0赞 João Mendes 10/24/2023
我不得不将示例中的 ltsc2022 图像换成 ltsc2019 图像,但除此之外,这就像一个魅力!