You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#启动子进程时控制台输出丢失问题排查(UnityCI Docker容器下Unity批处理场景)

问题分析与解决方案

我一眼就看到了你的C#代码里的参数拼接错误,这是导致输出丢失的核心原因,另外还有几个小细节需要调整,咱们一步步来:

1. 核心问题:Bash命令的参数解析错误

你在C#里构造的Bash参数是:

Arguments = $"-c unity-editor \"{argsString}\""

这会让Bash执行的命令变成:

unity-editor "-projectPath myPath -executeMethod myMethod -logFile -"

也就是说,Unity会把整个带引号的字符串当成一个单独的参数来处理,而不是拆分出-projectPath、myPath等多个参数。Unity根本没接收到正确的命令参数,自然不会产生预期的输出。

修正方法

正确的做法是直接把完整的Unity命令作为-c的参数,用外层双引号包裹整个命令,避免空格导致的解析问题:

Arguments = $"-c \"unity-editor {argsString}\""

2. 补充:重定向标准错误输出

你的UnityCI脚本里用了xvfb-run -ae /dev/stdout,这个参数是把XVFB的错误输出重定向到标准输出,但Unity本身的错误日志可能还是会输出到stderr。你当前的C#代码里RedirectStandardError = false,这会导致这部分输出丢失。建议把它设为true,并同样监听错误输出:

RedirectStandardError = true,
// 然后添加错误输出的监听
proc.ErrorDataReceived += OnErrorDataReceived;
proc.BeginErrorReadLine();

// 对应的处理方法
void OnErrorDataReceived(object obj, DataReceivedEventArgs args) {
    if(!string.IsNullOrEmpty(args.Data))
        Console.WriteLine(args.Data);
}

3. 额外验证:解决输出缓冲问题

有些程序在非交互式终端下会缓冲输出,导致内容不会实时显示。你可以尝试在Unity命令前添加stdbuf来强制关闭缓冲:

Arguments = $"-c \"stdbuf -o0 unity-editor {argsString}\""

stdbuf -o0会让标准输出无缓冲,确保内容能实时传递到你的C#进程。

完整修正后的C#代码

void StartProcess() { 
    string argsString = "-projectPath myPath -executeMethod myMethod -logFile -"; 
    ProcessStartInfo startInfo = new ProcessStartInfo { 
        FileName = "/bin/bash", 
        Arguments = $"-c \"stdbuf -o0 unity-editor {argsString}\"", 
        RedirectStandardOutput = true, 
        RedirectStandardError = true, 
        UseShellExecute = false, 
        CreateNoWindow = true, 
    }; 
    using Process proc = Process.Start(startInfo); 
    proc.OutputDataReceived += OnOutputDataReceived; 
    proc.ErrorDataReceived += OnErrorDataReceived;
    proc.BeginOutputReadLine(); 
    proc.BeginErrorReadLine();
    proc.WaitForExit(); 
} 

void OnOutputDataReceived(object obj, DataReceivedEventArgs args) { 
    if(!string.IsNullOrEmpty(args.Data) && args.Data.StartsWith("["))
        Console.WriteLine(args.Data); 
}

void OnErrorDataReceived(object obj, DataReceivedEventArgs args) { 
    if(!string.IsNullOrEmpty(args.Data))
        Console.WriteLine(args.Data); 
}

为什么直接用Bash执行没问题?

因为你直接在Bash里输入unity-editor -projectPath...时,Bash会自动把空格作为参数分隔符,正确拆分每个参数传递给Unity脚本。而C#里错误的引号包裹破坏了这个拆分逻辑,导致Unity无法正确执行命令。

内容的提问来源于stack exchange,提问作者Rurre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 00:09:10