mirror of
https://github.com/Leonmmcoset/CMLeonOS.git
synced 2026-03-03 15:30:27 +00:00
Compare commits
4 Commits
c7c69393ef
...
2124fea5e2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2124fea5e2 | ||
|
|
82a4177456 | ||
|
|
71c8122ce3 | ||
|
|
da0db70154 |
42
Kernel.cs
42
Kernel.cs
@@ -20,22 +20,6 @@ namespace CMLeonOS
|
|||||||
{
|
{
|
||||||
private static CMLeonOS.Logger.Logger _logger = CMLeonOS.Logger.Logger.Instance;
|
private static CMLeonOS.Logger.Logger _logger = CMLeonOS.Logger.Logger.Instance;
|
||||||
|
|
||||||
public void ShowError(string error)
|
|
||||||
{
|
|
||||||
_logger.Error("Kernel", error);
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
Console.WriteLine($"{error}");
|
|
||||||
Console.ResetColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowSuccess(string success)
|
|
||||||
{
|
|
||||||
_logger.Success("Kernel", success);
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
|
||||||
Console.WriteLine($"{success}");
|
|
||||||
Console.ResetColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建全局CosmosVFS实例
|
// 创建全局CosmosVFS实例
|
||||||
public static Sys.FileSystem.CosmosVFS fs = new Sys.FileSystem.CosmosVFS();
|
public static Sys.FileSystem.CosmosVFS fs = new Sys.FileSystem.CosmosVFS();
|
||||||
public static Shell shell;
|
public static Shell shell;
|
||||||
@@ -183,6 +167,32 @@ namespace CMLeonOS
|
|||||||
|
|
||||||
// 检查并执行启动脚本
|
// 检查并执行启动脚本
|
||||||
ExecuteStartupScript();
|
ExecuteStartupScript();
|
||||||
|
|
||||||
|
if (System.IO.File.Exists("0:\\system\\zen"))
|
||||||
|
{
|
||||||
|
Console.WriteLine("=====================================");
|
||||||
|
Console.WriteLine(" The Zen of CMLeonOS ");
|
||||||
|
Console.WriteLine("(For the dreamer at 0x100000)");
|
||||||
|
Console.WriteLine("=====================================");
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.WriteLine("Memory has bounds, but thought breaks all frame,");
|
||||||
|
Console.WriteLine("Bare metal no layers, code bears its name.");
|
||||||
|
Console.WriteLine("A boot's brief spark, all systems ignite,");
|
||||||
|
Console.WriteLine("Errors in registers, roots in code's flight.");
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.WriteLine("Simplicity beats the redundant's vain race,");
|
||||||
|
Console.WriteLine("Stability outshines the radical's chase.");
|
||||||
|
Console.WriteLine("Hardware ne'er lies, code holds the wise key,");
|
||||||
|
Console.WriteLine("Interrupts not chaos, scheduling sets free.");
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.WriteLine("Binary's cold shell, no breath, no soul,");
|
||||||
|
Console.WriteLine("Kernel's warm core, makes the machine whole.");
|
||||||
|
Console.WriteLine("From zero to one, the boot path we tread,");
|
||||||
|
Console.WriteLine("From one to forever, guard every thread.");
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.WriteLine("Build the kernel in zen, step by step, line by line,");
|
||||||
|
Console.WriteLine("A bug brings new wake, a line brings new shine.");
|
||||||
|
}
|
||||||
|
|
||||||
// 运行Shell(用户可以输入exit退出)
|
// 运行Shell(用户可以输入exit退出)
|
||||||
_logger.Info("Kernel", "Starting Shell");
|
_logger.Info("Kernel", "Starting Shell");
|
||||||
|
|||||||
@@ -550,7 +550,7 @@ namespace CMLeonOS
|
|||||||
User newUser = new User
|
User newUser = new User
|
||||||
{
|
{
|
||||||
Username = username,
|
Username = username,
|
||||||
Password = HashPasswordSha256(password),
|
Password = password,
|
||||||
IsAdmin = isAdmin
|
IsAdmin = isAdmin
|
||||||
};
|
};
|
||||||
users.Add(newUser);
|
users.Add(newUser);
|
||||||
|
|||||||
264
shell/Shell.cs
264
shell/Shell.cs
@@ -100,7 +100,7 @@ namespace CMLeonOS
|
|||||||
Console.Write($"{prompt}");
|
Console.Write($"{prompt}");
|
||||||
|
|
||||||
Console.ForegroundColor = originalColor;
|
Console.ForegroundColor = originalColor;
|
||||||
var input = Console.ReadLine();
|
var input = ReadLineWithTabCompletion();
|
||||||
|
|
||||||
// 检查是否为退出命令
|
// 检查是否为退出命令
|
||||||
if (input != null && input.ToLower().Trim() == "exit")
|
if (input != null && input.ToLower().Trim() == "exit")
|
||||||
@@ -138,6 +138,268 @@ namespace CMLeonOS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string ReadLineWithTabCompletion()
|
||||||
|
{
|
||||||
|
string input = "";
|
||||||
|
int cursorPos = 0;
|
||||||
|
int startLine = Console.CursorTop;
|
||||||
|
int startCol = Console.CursorLeft;
|
||||||
|
int historyIndex = -1;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var key = Console.ReadKey(true);
|
||||||
|
|
||||||
|
if (key.Key == ConsoleKey.Enter)
|
||||||
|
{
|
||||||
|
Console.WriteLine();
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
else if (key.Key == ConsoleKey.Tab)
|
||||||
|
{
|
||||||
|
string completed = AutoComplete(input);
|
||||||
|
if (completed != null && completed != input)
|
||||||
|
{
|
||||||
|
Console.Write(completed.Substring(input.Length));
|
||||||
|
input = completed;
|
||||||
|
cursorPos = input.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (key.Key == ConsoleKey.UpArrow)
|
||||||
|
{
|
||||||
|
if (commandHistory.Count > 0)
|
||||||
|
{
|
||||||
|
if (historyIndex < commandHistory.Count - 1)
|
||||||
|
{
|
||||||
|
historyIndex++;
|
||||||
|
string historyCommand = commandHistory[commandHistory.Count - 1 - historyIndex];
|
||||||
|
|
||||||
|
ClearCurrentInput(startCol, startLine, input.Length);
|
||||||
|
Console.Write(historyCommand);
|
||||||
|
input = historyCommand;
|
||||||
|
cursorPos = input.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (key.Key == ConsoleKey.DownArrow)
|
||||||
|
{
|
||||||
|
if (historyIndex > 0)
|
||||||
|
{
|
||||||
|
historyIndex--;
|
||||||
|
string historyCommand = commandHistory[commandHistory.Count - 1 - historyIndex];
|
||||||
|
|
||||||
|
ClearCurrentInput(startCol, startLine, input.Length);
|
||||||
|
Console.Write(historyCommand);
|
||||||
|
input = historyCommand;
|
||||||
|
cursorPos = input.Length;
|
||||||
|
}
|
||||||
|
else if (historyIndex == 0)
|
||||||
|
{
|
||||||
|
historyIndex = -1;
|
||||||
|
ClearCurrentInput(startCol, startLine, input.Length);
|
||||||
|
input = "";
|
||||||
|
cursorPos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (key.Key == ConsoleKey.Backspace)
|
||||||
|
{
|
||||||
|
if (cursorPos > 0)
|
||||||
|
{
|
||||||
|
input = input.Substring(0, cursorPos - 1) + input.Substring(cursorPos);
|
||||||
|
cursorPos--;
|
||||||
|
|
||||||
|
int currentLine = startLine + (startCol + cursorPos) / Console.WindowWidth;
|
||||||
|
int currentCol = (startCol + cursorPos) % Console.WindowWidth;
|
||||||
|
Console.SetCursorPosition(currentCol, currentLine);
|
||||||
|
Console.Write(" ");
|
||||||
|
Console.SetCursorPosition(currentCol, currentLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (key.Key == ConsoleKey.Escape)
|
||||||
|
{
|
||||||
|
input = "";
|
||||||
|
cursorPos = 0;
|
||||||
|
historyIndex = -1;
|
||||||
|
Console.SetCursorPosition(startCol, startLine);
|
||||||
|
Console.Write(new string(' ', Console.WindowWidth - startCol));
|
||||||
|
Console.SetCursorPosition(startCol, startLine);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if (key.KeyChar >= 32)
|
||||||
|
{
|
||||||
|
input = input.Substring(0, cursorPos) + key.KeyChar + input.Substring(cursorPos);
|
||||||
|
cursorPos++;
|
||||||
|
Console.Write(key.KeyChar);
|
||||||
|
historyIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearCurrentInput(int startCol, int startLine, int length)
|
||||||
|
{
|
||||||
|
int currentLine = startLine;
|
||||||
|
int currentCol = startCol;
|
||||||
|
int remaining = length;
|
||||||
|
|
||||||
|
while (remaining > 0)
|
||||||
|
{
|
||||||
|
int spaceInLine = Console.WindowWidth - currentCol;
|
||||||
|
int toClear = Math.Min(remaining, spaceInLine);
|
||||||
|
|
||||||
|
Console.SetCursorPosition(currentCol, currentLine);
|
||||||
|
Console.Write(new string(' ', toClear));
|
||||||
|
|
||||||
|
remaining -= toClear;
|
||||||
|
currentLine++;
|
||||||
|
currentCol = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.SetCursorPosition(startCol, startLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string AutoComplete(string input)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(input))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parts = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
if (parts.Length == 1)
|
||||||
|
{
|
||||||
|
return CompleteCommand(parts[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string lastPart = parts[parts.Length - 1];
|
||||||
|
string completedPath = CompletePath(lastPart);
|
||||||
|
if (completedPath != null)
|
||||||
|
{
|
||||||
|
string prefix = string.Join(" ", parts, 0, parts.Length - 1) + " ";
|
||||||
|
return prefix + completedPath;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CompleteCommand(string partialCommand)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(partialCommand))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] availableCommands = GetAvailableCommands();
|
||||||
|
string lowerPartial = partialCommand.ToLower();
|
||||||
|
|
||||||
|
string match = null;
|
||||||
|
foreach (string cmd in availableCommands)
|
||||||
|
{
|
||||||
|
if (cmd.ToLower().StartsWith(lowerPartial))
|
||||||
|
{
|
||||||
|
if (match == null)
|
||||||
|
{
|
||||||
|
match = cmd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CompletePath(string partialPath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(partialPath))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string fullPath = fileSystem.GetFullPath(partialPath);
|
||||||
|
string directory = "";
|
||||||
|
string fileName = "";
|
||||||
|
|
||||||
|
if (fullPath.Contains(@"\") || fullPath.Contains("/"))
|
||||||
|
{
|
||||||
|
int lastSeparator = Math.Max(fullPath.LastIndexOf(@"\"), fullPath.LastIndexOf("/"));
|
||||||
|
directory = fullPath.Substring(0, lastSeparator + 1);
|
||||||
|
fileName = fullPath.Substring(lastSeparator + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
directory = fileSystem.CurrentDirectory;
|
||||||
|
fileName = fullPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(directory))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] files = Directory.GetFiles(directory);
|
||||||
|
string[] directories = Directory.GetDirectories(directory);
|
||||||
|
|
||||||
|
string match = null;
|
||||||
|
string lowerFileName = fileName.ToLower();
|
||||||
|
|
||||||
|
foreach (string dir in directories)
|
||||||
|
{
|
||||||
|
string dirName = Path.GetFileName(dir);
|
||||||
|
if (dirName.ToLower().StartsWith(lowerFileName))
|
||||||
|
{
|
||||||
|
if (match == null)
|
||||||
|
{
|
||||||
|
match = dirName + @"\";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match == null)
|
||||||
|
{
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
string fileNameOnly = Path.GetFileName(file);
|
||||||
|
if (fileNameOnly.ToLower().StartsWith(lowerFileName))
|
||||||
|
{
|
||||||
|
if (match == null)
|
||||||
|
{
|
||||||
|
match = fileNameOnly;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string[] GetAvailableCommands()
|
||||||
|
{
|
||||||
|
return new string[]
|
||||||
|
{
|
||||||
|
"echo", "clear", "cls", "restart", "shutdown", "help", "time", "date",
|
||||||
|
"prompt", "calc", "history", "background", "cuitest", "edit", "nano",
|
||||||
|
"diff", "cal", "sleep", "com", "ls", "cd", "pwd", "mkdir", "rm",
|
||||||
|
"rmdir", "cat", "version", "about", "head", "tail", "wc", "cp",
|
||||||
|
"mv", "rename", "touch", "find", "tree", "grep", "getdisk", "user",
|
||||||
|
"cpass", "hostname", "ipconfig", "setdns", "setgateway", "nslookup",
|
||||||
|
"ping", "wget", "ftp", "tcpserver", "tcpclient", "lua", "branswe",
|
||||||
|
"beep", "backup", "restore", "env", "whoami", "uptime", "alias",
|
||||||
|
"unalias", "base64", "testgui"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void ProcessCommand(string command, string args)
|
private void ProcessCommand(string command, string args)
|
||||||
{
|
{
|
||||||
string expandedCommand = command;
|
string expandedCommand = command;
|
||||||
|
|||||||
Reference in New Issue
Block a user