当我们为 iOS 构建 Unity 项目时,它会生成一个使用 Cocoapods 的 Xcode 项目。我正在尝试制作一个构建后处理脚本(C#,在 Unity 编辑器中运行)来编辑 Podfile,然后在构建目录中运行
pod install
。
我尝试了几种不同的方法来运行
pod install
,但都以以下两种方式之一失败:
private static void ExecuteProcess(string directory, string argument) {
try {
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo() {
FileName = "/bin/bash",
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
WorkingDirectory = directory,
Arguments = " -c \"" + argument + " \""
};
System.Diagnostics.Process myProcess = new System.Diagnostics.Process {
StartInfo = startInfo
};
myProcess.Start();
while (!myProcess.StandardOutput.EndOfStream) {
var line = myProcess.StandardOutput.ReadLine();
UnityEngine.Debug.Log(line);
}
} catch (System.Exception e) {
UnityEngine.Debug.Log(e);
}
}
private static void TryInstallPods() {
const string BUILDS_PATH = "./Builds";
string shellScriptPath = Path.Join(BUILDS_PATH, "podinstall.sh");
// Outputs nothing
File.WriteAllText(shellScriptPath, "pod install --verbose");
ExecuteProcess(BUILDS_PATH, "sh podinstall.sh");
// Outputs "CDN: trunk Relative path: CocoaPods-version.yml exists! Returning local because checking is only performed in repo update"
File.WriteAllText(shellScriptPath, "/usr/local/bin/pod install --verbose");
ExecuteProcess(BUILDS_PATH, "sh podinstall.sh");
// Outputs nothing
ExecuteProcess(BUILDS_PATH, "pod install --verbose");
// Outputs "CDN: trunk Relative path: CocoaPods-version.yml exists! Returning local because checking is only performed in repo update"
ExecuteProcess(BUILDS_PATH, "/usr/local/bin/pod install --verbose");
// For reference, this works as expected for the build directory:
ExecuteProcess(BUILDS_PATH, "ls");
// This also works as expected:
ExecuteProcess(BUILDS_PATH, "/usr/local/bin/pod --help");
// This produces no output:
ExecuteProcess(BUILDS_PATH, "pod --help");
}
注意这个shell脚本是由代码生成的:
podinstall.sh
/usr/local/bin/pod install --verbose
pod install --verbose
不会产生任何输出,无论是直接调用还是从 shell 脚本内部调用。"/usr/local/bin/pod install --verbose"
生成输出“CDN:主干相对路径:CocoaPods-version.yml 存在!返回本地,因为仅在存储库更新中执行检查”,无论是直接调用还是从 shell 脚本内部调用。没有发生任何其他事情,并且 pod 配置也没有更新。如果尝试此处描述的方法,我会得到相同的结果:https://forum.unity.com/threads/ adjustment-pods-pods-xcproject-after-pod-install.1406500/
但是,如果我在构建文件夹中打开终端窗口并在其中键入命令,则任何变体都可以工作:
% pod install --verbose
% /usr/local/bin/pod install --verbose
% sh podinstall.sh
过程不死锁;删除标准输入和输出的方向不会使
pod install
命令起作用(通过检查 Podfile.lock
并看到它没有改变来验证)。
为什么当我在终端窗口中输入这些命令时它们会起作用,但当我尝试从 C#/Unity 中的进程中运行它们时却不起作用?
注意:我已经重新格式化了这个问题的代码;这个问题可能包含原始代码中不存在的拼写错误。
user246821 帮助我指明了正确的方向。将错误输出重定向到控制台后,我发现了一条错误消息,
pod install
要求将shell设置为UTF-8。向进程添加环境变量可以解决此问题:
private static void TryInstallPods() {
RunCmd("/bin/bash", BUILDS_PATH, "/usr/local/bin/pod install");
}
private static void RunCmd(string exePath, string directory, string arguments = null) {
ProcessStartInfo startInfo = new ProcessStartInfo(exePath, arguments);
startInfo.Arguments = " -c \"" + arguments + " \"";
startInfo.WorkingDirectory = directory;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = false;
startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.ErrorDialog = false;
startInfo.Environment["LANG"] = "en_US.UTF-8"; //REQUIRED FOR POD INSTALL
using (Process p = new Process { StartInfo = startInfo, EnableRaisingEvents = true }) {
p.ErrorDataReceived += (sender, e) => {
if (!System.String.IsNullOrEmpty(e.Data)) {
UnityEngine.Debug.Log("Error: " + e.Data);
}
};
p.OutputDataReceived += (sender, e) => {
if (!System.String.IsNullOrEmpty(e.Data)) {
UnityEngine.Debug.Log("Output: " + e.Data);
}
};
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
p.WaitForExit();
}
}