Files
crosslangdevstudio/CrossLangShell.cs
2025-08-31 00:25:32 -05:00

270 lines
9.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace CrossLangDevStudio;
class CrossLangShell
{
private static CrossLangSettings? settings = null;
public static CrossLangSettings Settings
{
get
{
if (settings != null) return settings;
var config = CrossLangConfigDirectory;
if (!string.IsNullOrWhiteSpace(config))
{
var devStudioDir = Path.Combine(config, "DevStudio");
Directory.CreateDirectory(devStudioDir);
var settingsFile = Path.Combine(devStudioDir, "Settings.json");
if (File.Exists(settingsFile))
{
settings = JsonConvert.DeserializeObject<CrossLangSettings>(File.ReadAllText(settingsFile));
}
}
return settings is null ? settings = new CrossLangSettings() : settings;
}
}
private static string _crosslang_config_dir = "";
public static string CrossLangConfigDirectory => string.IsNullOrWhiteSpace(_crosslang_config_dir) ? _crosslang_config_dir = GetCrossLangDirectory() : _crosslang_config_dir;
public static List<string> GetRecentProjects()
{
var config = CrossLangConfigDirectory;
if (string.IsNullOrWhiteSpace(config)) return new List<string>();
var devStudioDir = Path.Combine(config, "DevStudio");
Directory.CreateDirectory(devStudioDir);
var configPath = Path.Combine(devStudioDir, "Recents.json");
if (File.Exists(configPath))
{
var list = JsonConvert.DeserializeObject<List<string>>(File.ReadAllText(configPath));
if (list is not null) return list;
}
return new List<string>();
}
public static void OpenFolderInFileManager(string path)
{
using (Process p = new Process())
{
p.StartInfo.FileName = path;
p.StartInfo.UseShellExecute = true;
p.Start();
}
}
public static void EnsureRecent(string projectPath)
{
projectPath = Path.GetFullPath(projectPath).TrimEnd(Path.DirectorySeparatorChar);
var recents = GetRecentProjects();
if (recents.Contains(projectPath))
{
recents.Remove(projectPath);
}
recents.Insert(0, projectPath);
if (recents.Count > 5)
{
recents.RemoveRange(5, recents.Count - 5);
}
var config = CrossLangConfigDirectory;
if (string.IsNullOrWhiteSpace(config)) return;
var devStudioDir = Path.Combine(config, "DevStudio");
Directory.CreateDirectory(devStudioDir);
var configPath = Path.Combine(devStudioDir, "Recents.json");
File.WriteAllText(configPath, JsonConvert.SerializeObject(recents, Formatting.Indented));
}
public static string GetRealPath(string exec)
{
foreach (var item in (Environment.GetEnvironmentVariable("PATH") ?? "").Split(Path.PathSeparator))
{
var path = Path.Combine(item, exec);
if (File.Exists(path)) return path;
foreach (var ext in (Environment.GetEnvironmentVariable("PATHEXT") ?? "").Split(Path.PathSeparator))
{
if (File.Exists(path + ext)) return path + ext;
}
}
return "";
}
public static string CrossLangPath
{
get
{
var path = GetRealPath("crosslang");
return path;
}
}
public static bool HaveCrossLang
{
get
{
return !string.IsNullOrWhiteSpace(CrossLangPath);
}
}
public static void BuildProjectInFolder(string folder)
{
OpenTerminal(false, folder, CrossLangPath, "build");
}
public static void RunProjectInFolder(string folder)
{
OpenTerminal(true, folder, CrossLangPath, "run");
}
public static void OpenTerminalInFolder(string folder)
{
if (OperatingSystem.IsLinux())
{
OpenTerminal(false, folder, "", []);
}
}
public static void OpenTerminal(bool keepOpen, string workingDirectory, string commandName, params string[] args)
{
var preferedTerminalCommand = Settings.PreferedTerminalCommand;
if (!string.IsNullOrWhiteSpace(preferedTerminalCommand))
{
var firstArgs = preferedTerminalCommand.Split(" ");
using Process process = new();
process.StartInfo.UseShellExecute = false;
process.StartInfo.WorkingDirectory = workingDirectory;
process.StartInfo.FileName = firstArgs[0];
for (int i = 1; i < firstArgs.Length; i++)
{
process.StartInfo.ArgumentList.Add(firstArgs[i]);
}
foreach (var arg in args)
process.StartInfo.ArgumentList.Add(arg);
process.Start();
return;
}
if (OperatingSystem.IsLinux() || OperatingSystem.IsFreeBSD())
{
string konsole = GetRealPath("konsole");
string gnome_terminal = GetRealPath("gnome-terminal");
string xterm = GetRealPath("xterm");
if (File.Exists(konsole))
{
using Process process = new Process();
process.StartInfo.WorkingDirectory = workingDirectory;
process.StartInfo.FileName = konsole;
process.StartInfo.UseShellExecute = false;
if (commandName.Length != 0)
{
if (keepOpen)
process.StartInfo.ArgumentList.Add("--hold");
process.StartInfo.ArgumentList.Add("-e");
process.StartInfo.ArgumentList.Add(commandName);
foreach (var arg in args)
{
process.StartInfo.ArgumentList.Add(arg);
}
}
process.Start();
}
else if (File.Exists(gnome_terminal))
{
}
else if (File.Exists(xterm))
{
}
}
else if (OperatingSystem.IsWindows())
{
using Process process = new Process();
process.StartInfo.FileName = GetRealPath("cmd.exe");
if(commandName.Length > 0)
process.StartInfo.ArgumentList.Add(keepOpen ? "/K" : "/C");
process.StartInfo.CreateNoWindow = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WorkingDirectory = workingDirectory;
if(commandName.Length > 0)
process.StartInfo.ArgumentList.Add(commandName);
foreach (var item in args)
process.StartInfo.ArgumentList.Add(item);
process.Start();
}
}
private static string GetCrossLangDirectory()
{
string path = CrossLangPath;
if (string.IsNullOrWhiteSpace(path)) return "";
using Process process = new Process();
process.StartInfo.ArgumentList.Add("configdir");
process.StartInfo.FileName = path;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (process.Start())
{
process.WaitForExit();
var text = process.StandardOutput.ReadToEnd();
return (text ?? "").Replace("\n", "").Replace("\r", "");
}
return "";
}
internal static bool CreateProject(string templateName, string path)
{
string cpath = CrossLangPath;
if (string.IsNullOrWhiteSpace(cpath)) return false;
using Process process = new Process();
process.StartInfo.ArgumentList.Add("new");
process.StartInfo.ArgumentList.Add(templateName);
process.StartInfo.WorkingDirectory = path;
process.StartInfo.FileName = cpath;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (process.Start())
{
process.WaitForExit();
return process.ExitCode == 0;
}
return false;
}
}
public class CrossLangSettings
{
[JsonProperty("prefered_terminal_command")]
public string PreferedTerminalCommand { get; set; } = "";
[JsonProperty("prefered_project_directory")]
public string PreferedProjectDirectory { get; set; } = "";
[Newtonsoft.Json.JsonIgnore]
public string ProjectDirectory
{
get
{
if (!string.IsNullOrWhiteSpace(PreferedProjectDirectory))
return PreferedProjectDirectory;
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "CrossLangProjects");
Directory.CreateDirectory(path);
return path;
}
}
}