从C#代码激活conda环境(或手动打开cmd和从C#打开有什么区别?)

7

我想在Windows上使用conda环境(dlwin36)运行一个GPU加速的Python脚本。

我正在尝试激活dlwin36并执行一个脚本:

1)激活dlwin36

2)设置KERAS_BACKEND为tensorflow

3)python myscript.py

如果我在我的机器上手动打开cmd并写入:“activate dlwin36”,它能够正常工作。

但是当我尝试从C#打开cmd时,我收到以下消息:

"activate不被识别为内部或外部命令,可执行程序或批处理文件。"

我尝试使用以下方法:

命令链接:

var start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.Arguments = "/c activate dlwin36&&set KERAS_BACKEND=tensorflow&&python myscript.py";
Process.Start(start).WaitForExit();

我已经测试了几种UseShellExecute、LoadUserProfile和WorkingDirectory的变化。
重定向标准输入:
var commandsList = new List<string>();
commandsList.Add("activate dlwin36");
commandsList.Add("set KERAS_BACKEND=tensorflow");
commandsList.Add("python myscript.py");

var start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.UseShellExecute = false;
start.RedirectStandardInput = true;
var proc = Process.Start(start);
commandsList.ForEach(command => proc.StandardInput.WriteLine(command));

(我已经测试了几种LoadUserProfile和WorkingDirectory的变化)

在两种情况下,我得到了相同的错误。

看起来手动打开cmd和从c#打开它之间存在差异。

4个回答

13

关键是在执行任何其他操作之前,在cmd.exe中运行activate.bat。

// Set working directory and create process
var workingDirectory = Path.GetFullPath("Scripts");
var process = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "cmd.exe",
        RedirectStandardInput = true,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        WorkingDirectory = workingDirectory
    }
};
process.Start();
// Pass multiple commands to cmd.exe
using (var sw = process.StandardInput)
{
    if (sw.BaseStream.CanWrite)
    {
        // Vital to activate Anaconda
        sw.WriteLine("C:\\PathToAnaconda\\anaconda3\\Scripts\\activate.bat");
        // Activate your environment
        sw.WriteLine("activate your-environment");
        // Any other commands you want to run
        sw.WriteLine("set KERAS_BACKEND=tensorflow");
        // run your script. You can also pass in arguments
        sw.WriteLine("python YourScript.py");
    }
}

// read multiple output lines
while (!process.StandardOutput.EndOfStream)
{
    var line = process.StandardOutput.ReadLine();
    Console.WriteLine(line);
}

2
非常感谢!您可以在Anaconda提示符上右键单击并转到"属性",在目标部分找到Anacaonda正在使用的完整命令: %windir%\System32\cmd.exe "/K" C:\Users\na\AppData\Local\Continuum\anaconda3\Scripts\activate.bat C:\Users\na\AppData\Local\Continuum\anaconda3。 - Nabil.A

1

您需要使用环境中的python.exe。例如:

Process proc = new Process();
proc.StartInfo.FileName = @"C:\path-to-Anaconda3\envs\tensorflow-gpu\python.exe";

或者在您的情况下:
start.Arguments = "/c activate dlwin36&&set KERAS_BACKEND=tensorflow&&\"path-to-Anaconda3\envs\tensorflow-gpu\python.exe\" myscript.py";

1

我花了一些时间在这方面的工作上,这是唯一对我有效的方法:运行一个批处理文件来激活conda环境,然后在Python中发出命令,就像这样。我们称之为run_script.bat:

call C:\Path-to-Anaconda\Scripts\activate.bat myenv
set KERAS_BACKEND=tensorflow
python YourScript.py
exit

(注意在调用activate批处理文件之前使用了call关键字。)
之后,您可以从C#中运行它,就像上面展示的那样。
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.Arguments = "/K c:\\path_to_batch\\run_script.bat";
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.WorkingDirectory = "c:\\path_to_batch";
string stdout, stderr;
using (Process process = Process.Start(start))
{
    using (StreamReader reader = process.StandardOutput)
    {
        stdout = reader.ReadToEnd();
    }

    using (StreamReader reader = process.StandardError)
    {
        stderr = reader.ReadToEnd();
    }

    process.WaitForExit();
}

我正在使用C#动态生成批处理文件来设置必要的参数。

-1
如果这对未来的任何人有所帮助。我发现您必须从C:\驱动器运行激活。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接