C# 从虚拟环境运行 python 脚本

发布于 2025-01-12 03:28:30 字数 732 浏览 5 评论 0原文

我正在尝试使用 process 在 C# 中运行 python 脚本。

private void RunScript()
{
    ProcessStartInfo processStartInfo = new ProcessStartInfo("python.exe", "c:\\path\\to\\script\\PullRequest.py");
    processStartInfo.CreateNoWindow = true;
    processStartInfo.UseShellExecute = false;
    processStartInfo.RedirectStandardError = true;
    processStartInfo.RedirectStandardOutput = true;

    Process process = new Process();
    process.StartInfo = processStartInfo;
    process.Start();

    m_Output = process.StandardOutput.ReadToEnd();
    m_Error = process.StandardError.ReadToEnd();

    process.WaitForExit();
}

但是我收到以下错误:

No module named requests

如何从安装了请求模块的虚拟环境运行此脚本?

I am trying to run python script in c# with process.

private void RunScript()
{
    ProcessStartInfo processStartInfo = new ProcessStartInfo("python.exe", "c:\\path\\to\\script\\PullRequest.py");
    processStartInfo.CreateNoWindow = true;
    processStartInfo.UseShellExecute = false;
    processStartInfo.RedirectStandardError = true;
    processStartInfo.RedirectStandardOutput = true;

    Process process = new Process();
    process.StartInfo = processStartInfo;
    process.Start();

    m_Output = process.StandardOutput.ReadToEnd();
    m_Error = process.StandardError.ReadToEnd();

    process.WaitForExit();
}

However I got the following error :

No module named requests

How can i run this script from my virtual environment, where the requests module is installed ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陈独秀 2025-01-19 03:28:30

您必须首先激活您的虚拟环境,您只需在 .venv/bin 目录中指定 pippython 可执行文件的路径即可。

另一种方法是简单地激活虚拟环境,以便在 venv 中执行命令。
我目前在 Linux 容器中像这样运行它:

const string cmd = "bash";
const string args = "";
const string activateVenv = "source .venv/bin/activate";
var commandsToExecute = new List<string>(){
    "pip install -r requirements.txt",
    "python /path/to/script arg1 arg2 arg3"
};

var startInfo = new ProcessStartInfo
{
    RedirectStandardOutput = true,
    RedirectStandardInput = true,
    RedirectStandardError = true,
    UseShellExecute = false,
    CreateNoWindow = true,
    Arguments = args,
    FileName = cmd,
    WorkingDirectory = workingDirectory
};

var process = Process.Start(startInfo);
if (process == null)
    throw new Exception("Could not start process");

using var sw = process.StandardInput;
if (sw.BaseStream.CanWrite)
{
    sw.WriteLine(activateVenv);
    foreach (var command in commandsToExecute)
    {
        sw.WriteLine(command);
    }
    sw.Flush();
    sw.Close();
}

var sb = new StringBuilder();
while (!process.HasExited)
    sb.Append(process.StandardOutput.ReadToEnd());

var error = process.StandardError.ReadToEnd();
if (!string.IsNullOrEmpty(error))
    throw new Exception($"Something went wrong: \n{error}");

return sb.ToString();

这使我能够简单地将命令作为字符串列表传递,例如首先我运行 pip install -rrequirements.txt 然后 python /path/to/script arg1 arg2 arg3,因此不必分别处理 venv 目录中 pip 和 python 可执行文件的路径。

如果您在 Windows 上使用它,则必须更改调用它的方式以使用 powershell 和 venv 目录中的 Activate.ps1 脚本。可能有一些事情可以优化,但这就是我让它发挥作用的方式。如果我发现改进,我会更新答案。

You have to first activate your virtual environment, you can simply specify the path to the pip and python executables in the .venv/bin directory.

Another way is to simply activate the virtual environment so that the commands are executed in the venv.
I am currently running it like this in a Linux container:

const string cmd = "bash";
const string args = "";
const string activateVenv = "source .venv/bin/activate";
var commandsToExecute = new List<string>(){
    "pip install -r requirements.txt",
    "python /path/to/script arg1 arg2 arg3"
};

var startInfo = new ProcessStartInfo
{
    RedirectStandardOutput = true,
    RedirectStandardInput = true,
    RedirectStandardError = true,
    UseShellExecute = false,
    CreateNoWindow = true,
    Arguments = args,
    FileName = cmd,
    WorkingDirectory = workingDirectory
};

var process = Process.Start(startInfo);
if (process == null)
    throw new Exception("Could not start process");

using var sw = process.StandardInput;
if (sw.BaseStream.CanWrite)
{
    sw.WriteLine(activateVenv);
    foreach (var command in commandsToExecute)
    {
        sw.WriteLine(command);
    }
    sw.Flush();
    sw.Close();
}

var sb = new StringBuilder();
while (!process.HasExited)
    sb.Append(process.StandardOutput.ReadToEnd());

var error = process.StandardError.ReadToEnd();
if (!string.IsNullOrEmpty(error))
    throw new Exception(
quot;Something went wrong: \n{error}");

return sb.ToString();

This enables me to simply pass the commands as a list of strings, e.g. first I'm running pip install -r requirements.txt then python /path/to/script arg1 arg2 arg3, thus not having to deal with paths to the pip and python executables in the venv directory respectively.

If you are using it on Windows you would have to change the way it is invoked to use powershell and the Activate.ps1 script in the venv directory. There are probably a few things that could be optimized but this is how I got it working. If I find improvements I'll update the answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文