VR4RoboticArm2/VR4RoboticArm/Library/PackageCache/com.meta.xr.simulator/Editor/Utils/ProcessUtils.cs
IonutMocanu 48cccc22ad Main2
2025-09-08 11:13:29 +03:00

205 lines
7.3 KiB
C#

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
namespace Meta.XR.Simulator.Editor
{
internal class ProcessPort
{
public override string ToString()
{
return $"{ProcessName}({ProcessId}) ({Protocol} port {PortNumber})";
}
public string ProcessName { get; set; }
public int ProcessId { get; set; }
public string PortNumber { get; set; }
public string Protocol { get; set; }
}
internal class ProcessUtils
{
public virtual string GetProcessByPid(int pid)
{
string procName;
try
{
procName = Process.GetProcessById(pid).ProcessName;
}
catch (Exception ex)
{
UnityEngine.Debug.LogError(ex);
procName = "-";
}
return procName;
}
public virtual List<ProcessPort> GetProcessesByPort(string targetPort)
{
var ports = new List<ProcessPort>();
#if UNITY_EDITOR_OSX
var path = "lsof";
var args = $"-t -n -P -iTCP:{targetPort} -sTCP:LISTEN";
#elif UNITY_EDITOR_WIN
var path = "netstat.exe";
var args = "-a -n -o";
#else
return ports;
#endif
var (retCode, content) = ExecuteProcess(path, args);
#if UNITY_EDITOR_OSX
if(retCode == 1){
// According lsof man page, lsof will return 1 if there is no processes on specified port.
return ports;
}
#endif
if (retCode != 0)
{
UnityEngine.Debug.LogError(
$"{path} {args} call failed, exitCode={retCode}, content={content}");
return ports;
}
string[] rows = content.Split(Environment.NewLine);
foreach (string row in rows)
{
int processId = 0;
string protocol = "", portNumber = "";
#if UNITY_EDITOR_OSX
if(String.IsNullOrEmpty(row))
{
continue;
}
processId = Convert.ToInt32(row);
protocol = "TCPv6";
portNumber = targetPort;
#elif UNITY_EDITOR_WIN
Regex tokenRE = new Regex("\\s+");
Regex localAddressRE = new Regex(@"\[(.*?)\]");
string[] tokens = tokenRE.Split(row);
if (tokens.Length > 4 && (tokens[1].Equals("UDP") || tokens[1].Equals("TCP")))
{
string localAddress = localAddressRE.Replace(tokens[2], "1.1.1.1");
portNumber = localAddress.Split(':')[1];
if (targetPort != portNumber)
{
continue;
}
processId = 0;
try
{
processId = tokens[1].Equals("UDP")
? Convert.ToInt32(tokens[4])
: Convert.ToInt32(tokens[5]);
protocol = localAddress.Contains("1.1.1.1")
? String.Format("{0}v6", tokens[1])
: String.Format("{0}v4", tokens[1]);
}
catch (Exception ex)
{
UnityEngine.Debug.LogError(tokens[1] + " " + tokens[4] + " " + tokens[5]);
throw ex;
}
}
#endif
if (processId != 0)
{
string processName = GetProcessByPid(processId);
UnityEngine.Debug.Log($"Found {protocol} port {portNumber} used by {processName}({processId})");
ports.Add(new ProcessPort
{
Protocol = protocol,
PortNumber = portNumber,
ProcessName = processName,
ProcessId = processId
});
}
}
return ports;
}
public virtual void StopProcess(string processPort, string logContext)
{
var existingProcesses = Utils.ProcessUtils.GetProcessesByPort(processPort);
foreach (var existingProcess in existingProcesses)
{
Utils.LogUtils.ReportInfo(logContext, $"Stopping {existingProcess.ProcessName} with PID {existingProcess.ProcessId}");
var p = Process.GetProcessById(existingProcess.ProcessId);
p.Kill();
p.WaitForExit();
}
}
public virtual void LaunchProcess(string binaryPath, string arguments, string logContext, bool createWindow = true)
{
Utils.LogUtils.ReportInfo(logContext, "Launching " + binaryPath + ", createWindow=" + createWindow + ", arguments=" + arguments);
var newProcess = new Process();
newProcess.StartInfo.FileName = binaryPath;
newProcess.StartInfo.Arguments = arguments;
if (!createWindow)
{
newProcess.StartInfo.CreateNoWindow = true;
newProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
newProcess.StartInfo.UseShellExecute = false;
newProcess.StartInfo.RedirectStandardOutput = true;
newProcess.StartInfo.RedirectStandardError = true;
}
if (!newProcess.Start())
{
Utils.LogUtils.DisplayDialogOrError(logContext, "failed to launch " + binaryPath);
}
}
public virtual (int retCode, string contents) ExecuteProcess(string path, string args)
{
using var p = new Process();
var ps = new ProcessStartInfo
{
Arguments = args,
FileName = path,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
p.StartInfo = ps;
p.Start();
StreamReader stdOutput = p.StandardOutput;
StreamReader stdError = p.StandardError;
string content = stdOutput.ReadToEnd() + stdError.ReadToEnd();
p.WaitForExit();
int retCode = p.ExitCode;
return (retCode, content);
}
}
}