使用 Pythonnet 和 Pdb 调试 .Net 应用程序中的嵌入式 Python 代码

问题描述 投票:0回答:1

我有一个工作服务,我需要在其中调试 Python 代码。要执行 Python 代码,我需要使用 Pythonnet。 Pdb模块用于调试。 我正在尝试类似的事情:

python.txt:

import pdb

def func():
    pdb.set_trace()
    //code for debugging...
    

C#代码:

var pythonCode = File.ReadAllText(@"D:\python.txt");
Runtime.PythonDLL = @"D:\Python38\python38.dll";
PythonEngine.Initialize();

using (Py.GIL())
{
    var pyModule = Py.CreateScope("scope");
    pyModule.Exec(pythonCode);
}

Task.Run(() => 
    {
       using (Py.GIL())
       {
           pyModule.Exec("func()");
       }
    });

//some code

在 Python 代码中,我调用

pdb.set_trace()
,它等待进一步的调试器命令(n(ext)、s(tep) 等)输入到控制台。 在 C# 代码中,我在不同的线程中执行 Python 函数,以免阻塞等待输入命令的服务主线程。如果我使用 VSCode 的内部控制台手动输入命令,它就可以工作。但我需要通过我的工作服务从 GUI 传递调试器命令。

如何将这些命令传递到以编程方式从服务执行 python 代码的标准输入?

c# debugging .net-5 pdb python.net
1个回答
0
投票

我也有同样的问题。我想使用 pdb,但由于缺乏 I/O 流,很快就放弃了 PythonNet。我确实使用 Process 类型来运行 python.exe 以通过设置启动 python 控制台:

ProcessStartInfo psi = new ProcessStartInfo()
        {
            FileName = pythonExePath,
            Arguments = "-u -i -q",
            UseShellExecute = false,
            RedirectStandardInput = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        };
pythonProcess = new Process() { StartInfo = psi };
pythonProcess.Start();

pythonProcess.BeginOutputReadLine();
pythonProcess.BeginErrorReadLine();

outputBuffer = new ConcurrentQueue<string>();
errorBuffer = new ConcurrentQueue<string>();
        

pythonProcess.OutputDataReceived += (sender, args) =>
{
  if (!string.IsNullOrEmpty(args.Data))
     {
         outputBuffer.Enqueue(args.Data);
     }
  };

  pythonProcess.ErrorDataReceived += (sender, args) =>
  {
      if (!string.IsNullOrEmpty(args.Data))
      {
          errorBuffer.Enqueue(args.Data);
      }
  };

它以交互模式运行,并且是无缓冲的。如果我直接使用控制台我可以这样做:

>>> breakpoint()
--Return--
> <stdin>(1)<module>()->None
(Pdb) s
>>>

然后我可以继续执行新命令。 如果我尝试使用 C# 中的 Process 重新创建它,我会得到:

breakpoint()
--Return--
> <stdin>(1)<module>()->None
s
s
(Pdb) (Pdb) --Call--
> c:...python\lib\encodings\cp1251.py(14)decode()
-> def decode(self,input,errors='strict'):
(Pdb) > c:...\python\lib\encodings\cp1251.py(15)decode()
-> return codecs.charmap_decode(input,errors,decoding_table)
(Pdb) --Return--
> c:...\python\lib\encodings\cp1251.py(15)decode()->('\ns\n', 3)
-> return codecs.charmap_decode(input,errors,decoding_table)

您看到的代码片段既是发送的输入,也是接收的输出。这里发送的唯一命令是“breakpoint()”、“s”和“s”。第一个“s”不会产生任何结果,只有在发送第二个“s”后我才会得到回复。

备注:

  • 我尝试发送带或不带以下新行的命令。没有区别。
  • 只要我不使用 pdb,该过程就与控制台完全一样。
  • 在以下输入之前,我没有在输出中收到标准“(pdb)”,并且它会附加到以下输出。

这是我的第一篇文章,如果不符合标准,请道歉。我将不胜感激任何帮助。

© www.soinside.com 2019 - 2024. All rights reserved.