Compare commits

...

4 Commits

Author SHA1 Message Date
Leonmmcoset
c819327f85 更新Lua文档 2026-02-07 18:54:10 +08:00
Leonmmcoset
a71d6c40a6 Lua TUI+祖国统一万岁! 2026-02-07 17:26:43 +08:00
Leonmmcoset
6e87e44a15 新登录页面UI 2026-02-07 14:50:39 +08:00
Leonmmcoset
ae56d2f5b1 初始配置新UI 2026-02-07 13:25:15 +08:00
16 changed files with 1303 additions and 267 deletions

View File

@@ -306,139 +306,195 @@ namespace CMLeonOS
public void FirstTimeSetup()
{
Console.WriteLine("====================================");
Console.WriteLine(" First Time Setup");
Console.WriteLine("====================================");
Console.WriteLine();
Console.WriteLine("User Terms and Conditions:");
Console.WriteLine("====================================");
Console.WriteLine("1. This operating system is provided as-is without warranty");
Console.WriteLine("2. You are responsible for your data and backups");
Console.WriteLine("3. Unauthorized access attempts may be logged");
Console.WriteLine("4. System administrators have full access to all data");
Console.WriteLine("5. By using this system, you agree to these terms");
Console.WriteLine("6. Data privacy: Your personal data is stored locally");
Console.WriteLine("7. System updates may be installed automatically");
Console.WriteLine("8. No liability for data loss or corruption");
Console.WriteLine("9. Support available at: leonmmcoset@outlook.com");
Console.WriteLine("10. This license is for personal use only");
Console.WriteLine("====================================");
Console.WriteLine();
bool termsAccepted = false;
while (!termsAccepted)
{
Console.Write("Do you accept the User Terms? (yes/no): ");
string response = Console.ReadLine()?.ToLower();
if (response == "yes" || response == "y")
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.Clear();
var titleBar = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(0, 0, 80, 3), "First Time Setup", () => { }, false);
titleBar.Render();
var termsBox = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(5, 5, 70, 18), "User Terms and Conditions", () => { }, true);
termsBox.Render();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Gray, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.WriteLine("1. This operating system is provided as-is without warranty");
global::System.Console.SetCursorPosition(7, 8);
global::System.Console.WriteLine("2. You are responsible for your data and backups");
global::System.Console.SetCursorPosition(7, 9);
global::System.Console.WriteLine("3. Unauthorized access attempts may be logged");
global::System.Console.SetCursorPosition(7, 10);
global::System.Console.WriteLine("4. System administrators have full access to all data");
global::System.Console.SetCursorPosition(7, 11);
global::System.Console.WriteLine("5. By using this system, you agree to these terms");
global::System.Console.SetCursorPosition(7, 12);
global::System.Console.WriteLine("6. Data privacy: Your personal data is stored locally");
global::System.Console.SetCursorPosition(7, 13);
global::System.Console.WriteLine("7. System updates may be installed automatically");
global::System.Console.SetCursorPosition(7, 14);
global::System.Console.WriteLine("8. No liability for data loss or corruption");
global::System.Console.SetCursorPosition(7, 15);
global::System.Console.WriteLine("9. Support available at: leonmmcoset@outlook.com");
global::System.Console.SetCursorPosition(7, 16);
global::System.Console.WriteLine("10. This license is for personal use only");
global::System.Console.SetCursorPosition(7, 17);
global::System.Console.WriteLine("11. Use of this OS requires recognition of the one-China principle.");
bool termsAccepted = false;
while (!termsAccepted)
{
termsAccepted = true;
Console.WriteLine("Terms accepted.");
Console.WriteLine();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(5, 24);
global::System.Console.Write("Do you accept the User Terms? (yes/no): ");
string response = global::System.Console.ReadLine()?.ToLower();
if (response == "yes" || response == "y")
{
termsAccepted = true;
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(5, 24);
global::System.Console.Write("Terms accepted. ");
}
else if (response == "no" || response == "n")
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(5, 24);
global::System.Console.Write("You must accept the User Terms to continue.");
global::System.Threading.Thread.Sleep(2000);
Sys.Power.Reboot();
}
else
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(5, 24);
global::System.Console.Write("Invalid response. Please enter 'yes' or 'no'.");
}
}
else if (response == "no" || response == "n")
{
Console.WriteLine("You must accept the User Terms to continue.");
Console.WriteLine("Please restart the setup process.");
Thread.Sleep(2000);
Sys.Power.Reboot();
}
else
{
Console.WriteLine("Invalid response. Please enter 'yes' or 'no'.");
}
}
Console.WriteLine("Please set admin username and password:");
Console.Write("Username: ");
string username = Console.ReadLine();
while (string.IsNullOrWhiteSpace(username))
{
ShowError("Username cannot be empty.");
Console.Write("Username: ");
username = Console.ReadLine();
}
Console.WriteLine("Password: ");
string password = ReadPassword();
Console.WriteLine("Please confirm your password:");
string confirmPassword = ReadPassword();
while (password != confirmPassword)
{
ShowError("Passwords do not match. Please try again.");
Console.Write("Username: ");
username = Console.ReadLine();
global::System.Console.Clear();
titleBar.Render();
var setupBox = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(5, 5, 70, 12), "Admin Account Setup", () => { }, true);
setupBox.Render();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Username: ");
string username = global::System.Console.ReadLine();
while (string.IsNullOrWhiteSpace(username))
{
ShowError("Username cannot be empty.");
Console.Write("Username: ");
username = Console.ReadLine();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Username cannot be empty. ");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Username: ");
username = global::System.Console.ReadLine();
}
Console.WriteLine("Password: ");
password = ReadPassword();
Console.WriteLine("Please confirm your password:");
confirmPassword = ReadPassword();
}
try
{
User adminUser = new User
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 8);
global::System.Console.Write("Password: ");
string password = ReadPassword();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 9);
global::System.Console.Write("Confirm Password: ");
string confirmPassword = ReadPassword();
while (password != confirmPassword)
{
Username = username,
Password = password,
IsAdmin = true
};
users.Add(adminUser);
SaveUsers();
ShowSuccess("Admin user created successfully!");
Console.WriteLine();
Console.WriteLine("Please set system hostname:");
Console.Write("Hostname: ");
string hostname = Console.ReadLine();
while (string.IsNullOrWhiteSpace(hostname))
{
ShowError("Hostname cannot be empty.");
Console.Write("Hostname: ");
hostname = Console.ReadLine();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Passwords do not match. Please try again. ");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Username: ");
username = global::System.Console.ReadLine();
while (string.IsNullOrWhiteSpace(username))
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Username cannot be empty. ");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Username: ");
username = global::System.Console.ReadLine();
}
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 8);
global::System.Console.Write("Password: ");
password = ReadPassword();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 9);
global::System.Console.Write("Confirm Password: ");
confirmPassword = ReadPassword();
}
if (users.Count > 0)
try
{
users[0].Hostname = hostname;
SaveHostname();
ShowSuccess($"Hostname set to: {hostname}");
User adminUser = new User
{
Username = username,
Password = password,
IsAdmin = true
};
users.Add(adminUser);
SaveUsers();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Admin user created successfully! ");
global::System.Console.Clear();
titleBar.Render();
var hostnameBox = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(5, 5, 70, 8), "Hostname Setup", () => { }, true);
hostnameBox.Render();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Hostname: ");
string hostname = global::System.Console.ReadLine();
while (string.IsNullOrWhiteSpace(hostname))
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Hostname cannot be empty. ");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Hostname: ");
hostname = global::System.Console.ReadLine();
}
if (users.Count > 0)
{
users[0].Hostname = hostname;
SaveUsers();
}
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Hostname set successfully! ");
global::System.Threading.Thread.Sleep(2000);
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.Clear();
global::System.Console.SetCursorPosition(30, 12);
global::System.Console.Write("Setup completed!");
global::System.Console.SetCursorPosition(20, 13);
global::System.Console.Write("System will restart in 3 seconds...");
global::System.Threading.Thread.Sleep(3000);
Sys.Power.Reboot();
}
Console.WriteLine();
Console.WriteLine("System will restart in 3 seconds...");
Console.WriteLine("Please wait...");
Console.WriteLine();
for (int i = 3; i > 0; i--)
catch (Exception ex)
{
Console.Write($"\rRestarting in {i} seconds... ");
Thread.Sleep(1000);
ShowError($"Error creating admin user: {ex.Message}");
}
Console.WriteLine("\rRestarting now!");
Sys.Power.Reboot();
}
catch (Exception ex)
{
ShowError($"Error creating admin user: {ex.Message}");
}
}
private void CreateUserFolder(string username)
@@ -469,129 +525,78 @@ namespace CMLeonOS
public bool Login()
{
Console.WriteLine("====================================");
Console.WriteLine(" System Login");
Console.WriteLine("====================================");
// Console.ReadKey(true);
// 检测ALT+Space按键
bool useFixMode = false;
ConsoleKeyInfo keyInfo;
try
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.Clear();
var titleBar = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(0, 0, 80, 3), "System Login", () => { }, false);
titleBar.Render();
var loginBox = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(15, 8, 50, 10), "Login", () => { }, true);
loginBox.Render();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 10);
global::System.Console.Write("Username: ");
string username = global::System.Console.ReadLine();
if (string.IsNullOrWhiteSpace(username))
{
if (fixmode == true) {
keyInfo = Console.ReadKey(true);
if (keyInfo.Key == ConsoleKey.Spacebar && (keyInfo.Modifiers & ConsoleModifiers.Alt) != 0)
{
// 检测到ALT+Space进入修复模式
useFixMode = true;
Console.WriteLine();
Console.WriteLine("Fix Mode Activated");
Console.Write("Enter fix code: ");
string fixCode = "";
while (true)
{
var codeKey = Console.ReadKey(true);
if (codeKey.Key == ConsoleKey.Enter)
{
Console.WriteLine();
break;
}
else if (codeKey.Key == ConsoleKey.Backspace)
{
if (fixCode.Length > 0)
{
fixCode = fixCode.Substring(0, fixCode.Length - 1);
}
}
else
{
fixCode += codeKey.KeyChar;
Console.Write(codeKey.KeyChar);
}
}
if (fixCode == "FixMyComputer")
{
Console.WriteLine("Fix mode enabled!");
}
else
{
Console.WriteLine("Invalid fix code. Exiting fix mode.");
useFixMode = false;
}
}
}
else
{
// 正常登录流程
Console.Write("Username: ");
string username = Console.ReadLine();
if (string.IsNullOrWhiteSpace(username))
{
ShowError("Username cannot be empty.");
return false;
}
Console.Write("Password: ");
string password = ReadPassword();
// 查找用户
User foundUser = null;
foreach (User user in users)
{
if (user.Username.ToLower() == username.ToLower())
{
foundUser = user;
break;
}
}
if (foundUser == null)
{
ShowError("User not found.");
return false;
}
// 使用SHA256加密输入的密码后比较
string hashedInputPassword = HashPasswordSha256(password);
// Console.WriteLine($"Hashed Input Password: {hashedInputPassword}");
// Console.WriteLine($"Stored Password: {foundUser.Password}");
if (foundUser.Password != hashedInputPassword)
{
ShowError("Invalid password.");
return false;
}
ShowSuccess("Login successful!");
Console.Beep();
// 设置当前登录用户
currentLoggedInUser = foundUser;
// 创建用户文件夹
CreateUserFolder(foundUser.Username);
return true;
}
}
catch
{
// 如果读取按键失败,使用普通登录
ShowError("Error reading key input. Using normal login.");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 24);
global::System.Console.Write("Username cannot be empty. ");
global::System.Threading.Thread.Sleep(1000);
return false;
}
// 如果使用了修复模式返回true
if (useFixMode)
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 11);
global::System.Console.Write("Password: ");
string password = ReadPassword();
User foundUser = null;
foreach (User user in users)
{
return true;
if (user.Username.ToLower() == username.ToLower())
{
foundUser = user;
break;
}
}
return false;
if (foundUser == null)
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 24);
global::System.Console.Write("User not found. ");
global::System.Threading.Thread.Sleep(1000);
return false;
}
string hashedInputPassword = HashPasswordSha256(password);
if (foundUser.Password != hashedInputPassword)
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 24);
global::System.Console.Write("Invalid password. ");
global::System.Threading.Thread.Sleep(1000);
return false;
}
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 24);
global::System.Console.Write("Login successful! ");
// global::System.Console.WriteLine("Please wait... ");
global::System.Threading.Thread.Sleep(1500);
global::System.Console.ResetColor();
global::System.Console.Clear();
global::System.Console.Beep();
currentLoggedInUser = foundUser;
CreateUserFolder(foundUser.Username);
return true;
}
public bool AddUser(string args, bool isAdmin)

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace CMLeonOS.UI
{
@@ -589,4 +590,514 @@ namespace CMLeonOS.UI
RenderContent?.Invoke();
}
}
public class ListBox
{
public Rect Bounds { get; set; }
public List<string> Items { get; set; } = new List<string>();
public int SelectedIndex { get; set; } = 0;
public int ScrollOffset { get; set; } = 0;
public ConsoleColor SelectedColor { get; set; } = ConsoleColor.Yellow;
public ConsoleColor NormalColor { get; set; } = ConsoleColor.White;
public ConsoleColor BorderColor { get; set; } = ConsoleColor.White;
public ConsoleColor BackgroundColor { get; set; } = ConsoleColor.DarkBlue;
public bool MultiSelect { get; set; } = false;
public List<int> SelectedIndices { get; set; } = new List<int>();
public ListBox()
{
}
public ListBox(Rect bounds)
{
Bounds = bounds;
}
public void Render()
{
TUIHelper.SetColors(BorderColor, BackgroundColor);
TUIHelper.DrawBox(Bounds, string.Empty, BorderColor);
int startY = Bounds.Top + 1;
int maxHeight = Bounds.Height - 2;
for (int i = ScrollOffset; i < Items.Count && i < ScrollOffset + maxHeight; i++)
{
int y = startY + (i - ScrollOffset);
ConsoleColor color = (i == SelectedIndex) ? SelectedColor : NormalColor;
string prefix = (i == SelectedIndex) ? "> " : " ";
if (MultiSelect && SelectedIndices.Contains(i))
{
prefix = "[x] ";
}
else if (MultiSelect)
{
prefix = "[ ] ";
}
TUIHelper.SetColors(color, BackgroundColor);
Console.SetCursorPosition(Bounds.Left + 1, y);
Console.Write(prefix + TUIHelper.TruncateText(Items[i], Bounds.Width - 3));
}
if (Items.Count > maxHeight)
{
int scrollY = Bounds.Bottom - 1;
TUIHelper.SetColors(ConsoleColor.Gray, BackgroundColor);
Console.SetCursorPosition(Bounds.Right - 10, scrollY);
Console.Write($"({ScrollOffset + 1}/{(int)Math.Ceiling((double)Items.Count / maxHeight)})");
}
}
public bool HandleKey(ConsoleKeyInfo key)
{
if (key.Key == ConsoleKey.UpArrow || key.Key == ConsoleKey.PageUp)
{
SelectedIndex = (SelectedIndex - 1 + Items.Count) % Items.Count;
if (SelectedIndex < ScrollOffset) ScrollOffset = SelectedIndex;
return true;
}
if (key.Key == ConsoleKey.DownArrow || key.Key == ConsoleKey.PageDown)
{
SelectedIndex = (SelectedIndex + 1) % Items.Count;
int maxScroll = Items.Count - (Bounds.Height - 2);
if (SelectedIndex >= ScrollOffset + (Bounds.Height - 2))
{
ScrollOffset = SelectedIndex - (Bounds.Height - 3);
}
return true;
}
if (key.Key == ConsoleKey.Enter)
{
if (MultiSelect)
{
if (SelectedIndices.Contains(SelectedIndex))
{
SelectedIndices.Remove(SelectedIndex);
}
else
{
SelectedIndices.Add(SelectedIndex);
}
}
return true;
}
if (key.Key == ConsoleKey.Spacebar && MultiSelect)
{
if (SelectedIndices.Contains(SelectedIndex))
{
SelectedIndices.Remove(SelectedIndex);
}
else
{
SelectedIndices.Add(SelectedIndex);
}
return true;
}
return false;
}
}
public class CheckBox
{
public Point Position { get; set; }
public string Text { get; set; }
public bool IsChecked { get; set; } = false;
public bool IsFocused { get; set; } = false;
public ConsoleColor TextColor { get; set; } = ConsoleColor.White;
public ConsoleColor BoxColor { get; set; } = ConsoleColor.White;
public ConsoleColor BackgroundColor { get; set; } = ConsoleColor.Black;
public ConsoleColor FocusedTextColor { get; set; } = ConsoleColor.Yellow;
public ConsoleColor FocusedBoxColor { get; set; } = ConsoleColor.Yellow;
public ConsoleColor FocusedBackgroundColor { get; set; } = ConsoleColor.DarkBlue;
public CheckBox()
{
}
public CheckBox(Point position, string text)
{
Position = position;
Text = text;
}
public void Render()
{
if (IsFocused)
{
TUIHelper.SetColors(FocusedTextColor, FocusedBackgroundColor);
Console.SetCursorPosition(Position.X, Position.Y);
Console.Write(IsChecked ? "[X] " : "[ ] ");
Console.Write(Text);
}
else
{
TUIHelper.SetColors(TextColor, BackgroundColor);
Console.SetCursorPosition(Position.X, Position.Y);
Console.Write(IsChecked ? "[x] " : "[ ] ");
Console.Write(Text);
}
}
public bool HandleKey(ConsoleKeyInfo key)
{
if (key.Key == ConsoleKey.Enter || key.Key == ConsoleKey.Spacebar)
{
IsChecked = !IsChecked;
return true;
}
return false;
}
}
public class RadioButton
{
public Point Position { get; set; }
public string Text { get; set; }
public bool IsChecked { get; set; } = false;
public bool IsFocused { get; set; } = false;
public ConsoleColor TextColor { get; set; } = ConsoleColor.White;
public ConsoleColor BoxColor { get; set; } = ConsoleColor.White;
public ConsoleColor BackgroundColor { get; set; } = ConsoleColor.Black;
public string GroupName { get; set; } = string.Empty;
public ConsoleColor FocusedTextColor { get; set; } = ConsoleColor.Yellow;
public ConsoleColor FocusedBoxColor { get; set; } = ConsoleColor.Yellow;
public ConsoleColor FocusedBackgroundColor { get; set; } = ConsoleColor.DarkBlue;
public RadioButton()
{
}
public RadioButton(Point position, string text)
{
Position = position;
Text = text;
}
public void Render()
{
if (IsFocused)
{
TUIHelper.SetColors(FocusedTextColor, FocusedBackgroundColor);
Console.SetCursorPosition(Position.X, Position.Y);
Console.Write(IsChecked ? "(*) " : "( ) ");
Console.Write(Text);
}
else
{
TUIHelper.SetColors(TextColor, BackgroundColor);
Console.SetCursorPosition(Position.X, Position.Y);
Console.Write(IsChecked ? "(*) " : "( ) ");
Console.Write(Text);
}
}
public bool HandleKey(ConsoleKeyInfo key)
{
if (key.Key == ConsoleKey.Enter || key.Key == ConsoleKey.Spacebar)
{
IsChecked = !IsChecked;
return true;
}
return false;
}
}
public class TreeViewNode
{
public string Text { get; set; }
public List<TreeViewNode> Children { get; set; } = new List<TreeViewNode>();
public bool IsExpanded { get; set; } = false;
public int Level { get; set; } = 0;
public TreeViewNode Parent { get; set; }
public bool HasChildren => Children.Count > 0;
public TreeViewNode()
{
}
public TreeViewNode(string text)
{
Text = text;
}
}
public class TreeView
{
public Rect Bounds { get; set; }
public TreeViewNode Root { get; set; }
public List<TreeViewNode> SelectedNodes { get; set; } = new List<TreeViewNode>();
public ConsoleColor SelectedColor { get; set; } = ConsoleColor.Yellow;
public ConsoleColor NormalColor { get; set; } = ConsoleColor.White;
public ConsoleColor BorderColor { get; set; } = ConsoleColor.White;
public ConsoleColor BackgroundColor { get; set; } = ConsoleColor.DarkBlue;
public int ScrollOffset { get; set; } = 0;
public TreeView()
{
}
public TreeView(Rect bounds)
{
Bounds = bounds;
}
public void Render()
{
TUIHelper.SetColors(BorderColor, BackgroundColor);
TUIHelper.DrawBox(Bounds, string.Empty, BorderColor);
int startY = Bounds.Top + 1;
int maxHeight = Bounds.Height - 2;
List<TreeViewNode> visibleNodes = GetVisibleNodes();
for (int i = ScrollOffset; i < visibleNodes.Count && i < ScrollOffset + maxHeight; i++)
{
int y = startY + (i - ScrollOffset);
var node = visibleNodes[i];
ConsoleColor color = SelectedNodes.Contains(node) ? SelectedColor : NormalColor;
string prefix = GetNodePrefix(node);
TUIHelper.SetColors(color, BackgroundColor);
Console.SetCursorPosition(Bounds.Left + 1, y);
Console.Write(prefix + TUIHelper.TruncateText(node.Text, Bounds.Width - 3 - node.Level * 2));
}
if (visibleNodes.Count > maxHeight)
{
int scrollY = Bounds.Bottom - 1;
TUIHelper.SetColors(ConsoleColor.Gray, BackgroundColor);
Console.SetCursorPosition(Bounds.Right - 10, scrollY);
Console.Write($"({ScrollOffset + 1}/{(int)Math.Ceiling((double)visibleNodes.Count / maxHeight)})");
}
}
private List<TreeViewNode> GetVisibleNodes()
{
List<TreeViewNode> nodes = new List<TreeViewNode>();
if (Root != null)
{
AddVisibleNodes(Root, nodes);
}
return nodes;
}
private void AddVisibleNodes(TreeViewNode node, List<TreeViewNode> nodes)
{
nodes.Add(node);
if (node.IsExpanded)
{
foreach (var child in node.Children)
{
AddVisibleNodes(child, nodes);
}
}
}
private string GetNodePrefix(TreeViewNode node)
{
string prefix = "";
for (int i = 0; i < node.Level; i++)
{
prefix += " ";
}
if (node.HasChildren)
{
prefix += node.IsExpanded ? "- " : "+ ";
}
else
{
prefix += "+ ";
}
return prefix;
}
public bool HandleKey(ConsoleKeyInfo key)
{
var visibleNodes = GetVisibleNodes();
if (visibleNodes.Count == 0) return false;
if (key.Key == ConsoleKey.UpArrow || key.Key == ConsoleKey.PageUp)
{
int currentIndex = visibleNodes.FindIndex(n => SelectedNodes.Contains(n));
if (currentIndex > 0)
{
SelectedNodes.Clear();
SelectedNodes.Add(visibleNodes[currentIndex - 1]);
if (currentIndex - 1 < ScrollOffset) ScrollOffset = currentIndex - 1;
}
return true;
}
if (key.Key == ConsoleKey.DownArrow || key.Key == ConsoleKey.PageDown)
{
int currentIndex = visibleNodes.FindIndex(n => SelectedNodes.Contains(n));
if (currentIndex < visibleNodes.Count - 1)
{
SelectedNodes.Clear();
SelectedNodes.Add(visibleNodes[currentIndex + 1]);
int maxScroll = visibleNodes.Count - (Bounds.Height - 2);
if (currentIndex + 1 >= ScrollOffset + (Bounds.Height - 2))
{
ScrollOffset = (currentIndex + 1) - (Bounds.Height - 3);
}
}
return true;
}
if (key.Key == ConsoleKey.Enter || key.Key == ConsoleKey.Spacebar)
{
var currentNode = visibleNodes.FirstOrDefault(n => SelectedNodes.Contains(n));
if (currentNode != null && currentNode.HasChildren)
{
currentNode.IsExpanded = !currentNode.IsExpanded;
}
else if (currentNode != null)
{
if (SelectedNodes.Contains(currentNode))
{
SelectedNodes.Remove(currentNode);
}
else
{
SelectedNodes.Add(currentNode);
}
}
return true;
}
return false;
}
}
public class ScrollBar
{
public Point Position { get; set; }
public int Height { get; set; }
public int MaxValue { get; set; }
public int Value { get; set; } = 0;
public ConsoleColor BarColor { get; set; } = ConsoleColor.White;
public ConsoleColor BackgroundColor { get; set; } = ConsoleColor.DarkGray;
public ConsoleColor BorderColor { get; set; } = ConsoleColor.White;
public bool IsVertical { get; set; } = true;
public ScrollBar()
{
}
public ScrollBar(Point position, int height)
{
Position = position;
Height = height;
}
public void Render()
{
TUIHelper.SetColors(BorderColor, BackgroundColor);
if (IsVertical)
{
Console.SetCursorPosition(Position.X, Position.Y);
Console.Write('┌');
for (int i = 0; i < Height - 2; i++)
{
Console.SetCursorPosition(Position.X, Position.Y + 1 + i);
Console.Write('│');
}
Console.SetCursorPosition(Position.X, Position.Y + Height - 1);
Console.Write('└');
int barHeight = Height - 2;
int barPosition = (int)((double)Value / MaxValue * barHeight);
for (int i = 0; i < barHeight; i++)
{
Console.SetCursorPosition(Position.X, Position.Y + 1 + i);
if (i >= barPosition && i < barPosition + (int)((double)barHeight / MaxValue * Value))
{
Console.Write('█');
}
else
{
Console.Write('░');
}
}
}
else
{
Console.SetCursorPosition(Position.X, Position.Y);
Console.Write('┌');
for (int i = 0; i < Height - 2; i++)
{
Console.SetCursorPosition(Position.X + 1 + i, Position.Y);
Console.Write('─');
}
Console.SetCursorPosition(Position.X + Height - 1, Position.Y);
Console.Write('┐');
int barWidth = Height - 2;
int barPosition = (int)((double)Value / MaxValue * barWidth);
for (int i = 0; i < barWidth; i++)
{
Console.SetCursorPosition(Position.X + 1 + i, Position.Y);
if (i >= barPosition && i < barPosition + (int)((double)barWidth / MaxValue * Value))
{
Console.Write('█');
}
else
{
Console.Write('░');
}
}
}
}
public bool HandleKey(ConsoleKeyInfo key)
{
if (IsVertical)
{
if (key.Key == ConsoleKey.UpArrow)
{
Value = Math.Max(0, Value - 1);
return true;
}
if (key.Key == ConsoleKey.DownArrow)
{
Value = Math.Min(MaxValue, Value + 1);
return true;
}
if (key.Key == ConsoleKey.PageUp)
{
Value = Math.Max(0, Value - 10);
return true;
}
if (key.Key == ConsoleKey.PageDown)
{
Value = Math.Min(MaxValue, Value + 10);
return true;
}
}
else
{
if (key.Key == ConsoleKey.LeftArrow)
{
Value = Math.Max(0, Value - 1);
return true;
}
if (key.Key == ConsoleKey.RightArrow)
{
Value = Math.Min(MaxValue, Value + 1);
return true;
}
}
return false;
}
}
}

View File

@@ -33,11 +33,11 @@
</script>
<title>CMLeonOS官方文档站</title><meta name="description" content="CMLeonOS是一个基于微内核架构的操作系统它的目标是提供一个简单、可靠、安全的操作系统环境。">
<link rel="preload" href="/assets/style-BmL0kmLr.css" as="style"><link rel="stylesheet" href="/assets/style-BmL0kmLr.css">
<link rel="modulepreload" href="/assets/app-BITa06va.js"><link rel="modulepreload" href="/assets/404.html-B-2P5V78.js">
<link rel="prefetch" href="/assets/commands.html-CJdMGWM7.js" as="script"><link rel="prefetch" href="/assets/get-started.html-D_vM18Nz.js" as="script"><link rel="prefetch" href="/assets/lua.html-DxDsLuB0.js" as="script"><link rel="prefetch" href="/assets/index.html-DS7rXIvH.js" as="script">
<link rel="modulepreload" href="/assets/app-C2pVPwUc.js"><link rel="modulepreload" href="/assets/404.html-BozFi7tE.js">
<link rel="prefetch" href="/assets/commands.html-BVVm3joo.js" as="script"><link rel="prefetch" href="/assets/get-started.html-CVeJRoHk.js" as="script"><link rel="prefetch" href="/assets/lua.html-Cnr7xLDd.js" as="script"><link rel="prefetch" href="/assets/index.html-MspKP7L1.js" as="script">
</head>
<body>
<div id="app"><!--[--><div class="vp-theme-container" vp-container data-v-d32690b4><main class="page" data-v-d32690b4><div vp-content data-v-d32690b4><h1 data-v-d32690b4>404</h1><blockquote data-v-d32690b4>How did we get here?</blockquote><a class="route-link" href="/" data-v-d32690b4>Take me home</a></div></main></div><!--[--><!----><!--]--><!--]--></div>
<script type="module" src="/assets/app-BITa06va.js" defer></script>
<div id="app"><!--[--><div class="vp-theme-container" vp-container data-v-d32690b4><main class="page" data-v-d32690b4><div vp-content data-v-d32690b4><h1 data-v-d32690b4>404</h1><blockquote data-v-d32690b4>Looks like we&#39;ve got some broken links.</blockquote><a class="route-link" href="/" data-v-d32690b4>Take me home</a></div></main></div><!--[--><!----><!--]--><!--]--></div>
<script type="module" src="/assets/app-C2pVPwUc.js" defer></script>
</body>
</html>

View File

@@ -1 +1 @@
import{_ as e,c as o,b as a,o as n}from"./app-BITa06va.js";const l={};function r(s,t){return n(),o("div",null,[...t[0]||(t[0]=[a("p",null,"404 Not Found",-1)])])}const _=e(l,[["render",r]]),d=JSON.parse('{"path":"/404.html","title":"","lang":"zh-CN","frontmatter":{"layout":"NotFound"},"headers":[],"git":{},"filePathRelative":null}');export{_ as comp,d as data};
import{_ as e,c as o,b as a,o as n}from"./app-C2pVPwUc.js";const l={};function r(s,t){return n(),o("div",null,[...t[0]||(t[0]=[a("p",null,"404 Not Found",-1)])])}const _=e(l,[["render",r]]),d=JSON.parse('{"path":"/404.html","title":"","lang":"zh-CN","frontmatter":{"layout":"NotFound"},"headers":[],"git":{},"filePathRelative":null}');export{_ as comp,d as data};

View File

@@ -1 +1 @@
import{_ as t,c as a,a as l,o as s}from"./app-BITa06va.js";const n={};function i(o,e){return s(),a("div",null,[...e[0]||(e[0]=[l('<h1 id="配置教程" tabindex="-1"><a class="header-anchor" href="#配置教程"><span>配置教程</span></a></h1><h2 id="准备工作" tabindex="-1"><a class="header-anchor" href="#准备工作"><span>准备工作</span></a></h2><p>首先,准备一台实体机/虚拟机,确保这台机器等于或大于以下配置:</p><ul><li>处理器:一核以上</li><li>内存512MB以上</li><li>硬盘512MB以上</li><li>一个键盘</li><li>一个蜂鸣器或音频输出设备</li><li>建议装上AMD驱动的网卡Intel驱动的网卡似乎无法运行</li></ul><h2 id="配置硬盘" tabindex="-1"><a class="header-anchor" href="#配置硬盘"><span>配置硬盘</span></a></h2><p>使用PE或其它工具格式化硬盘注意只分一个区文件系统选择FAT32</p><h2 id="安装cmleonos" tabindex="-1"><a class="header-anchor" href="#安装cmleonos"><span>安装CMLeonOS</span></a></h2><p>将CMLeonOS的ISO文件挂载到虚拟机或实体机上启动后按照提示进行 First time setup。</p><p>在 First time setup 中系统会让你配置用户名、密码、主机名配置完后会进行重启重启之后正常登陆系统然后就可以开始使用CMLeonOS了。</p>',9)])])}const r=t(n,[["render",i]]),m=JSON.parse('{"path":"/get-started.html","title":"配置教程","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"准备工作","slug":"准备工作","link":"#准备工作","children":[]},{"level":2,"title":"配置硬盘","slug":"配置硬盘","link":"#配置硬盘","children":[]},{"level":2,"title":"安装CMLeonOS","slug":"安装cmleonos","link":"#安装cmleonos","children":[]}],"git":{"updatedTime":1770190333000,"contributors":[{"name":"Leonmmcoset","username":"Leonmmcoset","email":"testmod@qq.com","commits":1,"url":"https://github.com/Leonmmcoset"}],"changelog":[{"hash":"33510365f48beba3a56b2dc6afd4c54b1fbdab60","time":1770190333000,"email":"testmod@qq.com","author":"Leonmmcoset","message":"docs&amp;Lua input()"}]},"filePathRelative":"get-started.md"}');export{r as comp,m as data};
import{_ as t,c as a,a as l,o as s}from"./app-C2pVPwUc.js";const n={};function i(o,e){return s(),a("div",null,[...e[0]||(e[0]=[l('<h1 id="配置教程" tabindex="-1"><a class="header-anchor" href="#配置教程"><span>配置教程</span></a></h1><h2 id="准备工作" tabindex="-1"><a class="header-anchor" href="#准备工作"><span>准备工作</span></a></h2><p>首先,准备一台实体机/虚拟机,确保这台机器等于或大于以下配置:</p><ul><li>处理器:一核以上</li><li>内存512MB以上</li><li>硬盘512MB以上</li><li>一个键盘</li><li>一个蜂鸣器或音频输出设备</li><li>建议装上AMD驱动的网卡Intel驱动的网卡似乎无法运行</li></ul><h2 id="配置硬盘" tabindex="-1"><a class="header-anchor" href="#配置硬盘"><span>配置硬盘</span></a></h2><p>使用PE或其它工具格式化硬盘注意只分一个区文件系统选择FAT32</p><h2 id="安装cmleonos" tabindex="-1"><a class="header-anchor" href="#安装cmleonos"><span>安装CMLeonOS</span></a></h2><p>将CMLeonOS的ISO文件挂载到虚拟机或实体机上启动后按照提示进行 First time setup。</p><p>在 First time setup 中系统会让你配置用户名、密码、主机名配置完后会进行重启重启之后正常登陆系统然后就可以开始使用CMLeonOS了。</p>',9)])])}const r=t(n,[["render",i]]),m=JSON.parse('{"path":"/get-started.html","title":"配置教程","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"准备工作","slug":"准备工作","link":"#准备工作","children":[]},{"level":2,"title":"配置硬盘","slug":"配置硬盘","link":"#配置硬盘","children":[]},{"level":2,"title":"安装CMLeonOS","slug":"安装cmleonos","link":"#安装cmleonos","children":[]}],"git":{"updatedTime":1770190333000,"contributors":[{"name":"Leonmmcoset","username":"Leonmmcoset","email":"testmod@qq.com","commits":1,"url":"https://github.com/Leonmmcoset"}],"changelog":[{"hash":"33510365f48beba3a56b2dc6afd4c54b1fbdab60","time":1770190333000,"email":"testmod@qq.com","author":"Leonmmcoset","message":"docs&amp;Lua input()"}]},"filePathRelative":"get-started.md"}');export{r as comp,m as data};

View File

@@ -1 +1 @@
import{_ as e,c as t,o as a}from"./app-BITa06va.js";const o={};function m(s,i){return a(),t("div")}const c=e(o,[["render",m]]),l=JSON.parse('{"path":"/","title":"主页","lang":"zh-CN","frontmatter":{"home":true,"title":"主页","actions":[{"text":"开始配置","link":"/get-started.html","type":"primary"},{"text":"Lua 文档","link":"/lua.html","type":"secondary"},{"text":"命令列表","link":"/commands.html","type":"secondary"}],"features":[{"title":"安全用户系统","details":"用户系统是直接绑定在内核下的,通过 SHA-256 密码哈希算法对用户密码进行加密存储,确保用户密码的安全性。"},{"title":"Lua 脚本支持","details":"CMLeonOS支持 Lua 脚本,用户可以通过 Lua 脚本实现自定义功能。"},{"title":"网络","details":"CMLeonOS支持 TCP/IP 协议栈,用户可以通过网络连接到其他设备。"},{"title":"FTP 服务器","details":"CMLeonOS支持 FTP 服务器,用户可以通过 FTP 协议上传下载文件。"},{"title":"内置编辑器","details":"CMLeonOS支持内置编辑器用户可以直接在CMLeonOS中编辑文件。"},{"title":"硬盘存储","details":"CMLeonOS支持硬盘存储用户可以将文件持久存储在硬盘中。"},{"title":"命令别名","details":"CMLeonOS支持命令别名功能用户可以创建自定义命令快捷方式。"}]},"headers":[],"git":{"updatedTime":1770300033000,"contributors":[{"name":"Leonmmcoset","username":"Leonmmcoset","email":"testmod@qq.com","commits":2,"url":"https://github.com/Leonmmcoset"}],"changelog":[{"hash":"4384578fdb936483c76ffe61512a6530b54cf9ce","time":1770300033000,"email":"testmod@qq.com","author":"Leonmmcoset","message":"update"},{"hash":"33510365f48beba3a56b2dc6afd4c54b1fbdab60","time":1770190333000,"email":"testmod@qq.com","author":"Leonmmcoset","message":"docs&amp;Lua input()"}]},"filePathRelative":"README.md"}');export{c as comp,l as data};
import{_ as e,c as t,o as a}from"./app-C2pVPwUc.js";const o={};function m(s,i){return a(),t("div")}const c=e(o,[["render",m]]),l=JSON.parse('{"path":"/","title":"主页","lang":"zh-CN","frontmatter":{"home":true,"title":"主页","actions":[{"text":"开始配置","link":"/get-started.html","type":"primary"},{"text":"Lua 文档","link":"/lua.html","type":"secondary"},{"text":"命令列表","link":"/commands.html","type":"secondary"}],"features":[{"title":"安全用户系统","details":"用户系统是直接绑定在内核下的,通过 SHA-256 密码哈希算法对用户密码进行加密存储,确保用户密码的安全性。"},{"title":"Lua 脚本支持","details":"CMLeonOS支持 Lua 脚本,用户可以通过 Lua 脚本实现自定义功能。"},{"title":"网络","details":"CMLeonOS支持 TCP/IP 协议栈,用户可以通过网络连接到其他设备。"},{"title":"FTP 服务器","details":"CMLeonOS支持 FTP 服务器,用户可以通过 FTP 协议上传下载文件。"},{"title":"内置编辑器","details":"CMLeonOS支持内置编辑器用户可以直接在CMLeonOS中编辑文件。"},{"title":"硬盘存储","details":"CMLeonOS支持硬盘存储用户可以将文件持久存储在硬盘中。"},{"title":"命令别名","details":"CMLeonOS支持命令别名功能用户可以创建自定义命令快捷方式。"}]},"headers":[],"git":{"updatedTime":1770300033000,"contributors":[{"name":"Leonmmcoset","username":"Leonmmcoset","email":"testmod@qq.com","commits":2,"url":"https://github.com/Leonmmcoset"}],"changelog":[{"hash":"4384578fdb936483c76ffe61512a6530b54cf9ce","time":1770300033000,"email":"testmod@qq.com","author":"Leonmmcoset","message":"update"},{"hash":"33510365f48beba3a56b2dc6afd4c54b1fbdab60","time":1770190333000,"email":"testmod@qq.com","author":"Leonmmcoset","message":"docs&amp;Lua input()"}]},"filePathRelative":"README.md"}');export{c as comp,l as data};

View File

@@ -33,8 +33,8 @@
</script>
<title>命令列表 | CMLeonOS官方文档站</title><meta name="description" content="CMLeonOS是一个基于微内核架构的操作系统它的目标是提供一个简单、可靠、安全的操作系统环境。">
<link rel="preload" href="/assets/style-BmL0kmLr.css" as="style"><link rel="stylesheet" href="/assets/style-BmL0kmLr.css">
<link rel="modulepreload" href="/assets/app-BITa06va.js"><link rel="modulepreload" href="/assets/commands.html-CJdMGWM7.js">
<link rel="prefetch" href="/assets/get-started.html-D_vM18Nz.js" as="script"><link rel="prefetch" href="/assets/lua.html-DxDsLuB0.js" as="script"><link rel="prefetch" href="/assets/index.html-DS7rXIvH.js" as="script"><link rel="prefetch" href="/assets/404.html-B-2P5V78.js" as="script">
<link rel="modulepreload" href="/assets/app-C2pVPwUc.js"><link rel="modulepreload" href="/assets/commands.html-BVVm3joo.js">
<link rel="prefetch" href="/assets/get-started.html-CVeJRoHk.js" as="script"><link rel="prefetch" href="/assets/lua.html-Cnr7xLDd.js" as="script"><link rel="prefetch" href="/assets/index.html-MspKP7L1.js" as="script"><link rel="prefetch" href="/assets/404.html-BozFi7tE.js" as="script">
</head>
<body>
<div id="app"><!--[--><div class="vp-theme-container external-link-icon" vp-container><!--[--><header class="vp-navbar" vp-navbar><div class="vp-toggle-sidebar-button" title="toggle sidebar" aria-expanded="false" role="button" tabindex="0"><div class="icon" aria-hidden="true"><span></span><span></span><span></span></div></div><span><a class="route-link" href="/"><!----><span class="vp-site-name" aria-hidden="true">CMLeonOS官方文档站</span></a></span><div class="vp-navbar-items-wrapper" style=""><!--[--><!--]--><nav class="vp-navbar-items vp-hide-mobile" aria-label="site navigation"><!--[--><div class="vp-navbar-item"><a class="route-link auto-link" href="/" aria-label="主页"><!--[--><!--[--><!--]--><!--]-->主页<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/get-started.html" aria-label="配置教程"><!--[--><!--[--><!--]--><!--]-->配置教程<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/lua.html" aria-label="CMLeonOS Lua API 文档"><!--[--><!--[--><!--]--><!--]-->CMLeonOS Lua API 文档<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link route-link-active auto-link" href="/commands.html" aria-label="命令列表"><!--[--><!--[--><!--]--><!--]-->命令列表<!--[--><!--[--><!--]--><!--]--></a></div><!--]--></nav><!--[--><!--]--><button type="button" class="vp-toggle-color-mode-button" title="toggle color mode"><svg class="light-icon" viewbox="0 0 32 32" style=""><path d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6z" fill="currentColor"></path><path d="M5.394 6.813l1.414-1.415l3.506 3.506L8.9 10.318z" fill="currentColor"></path><path d="M2 15.005h5v2H2z" fill="currentColor"></path><path d="M5.394 25.197L8.9 21.691l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 25.005h2v5h-2z" fill="currentColor"></path><path d="M21.687 23.106l1.414-1.415l3.506 3.506l-1.414 1.414z" fill="currentColor"></path><path d="M25 15.005h5v2h-5z" fill="currentColor"></path><path d="M21.687 8.904l3.506-3.506l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 2.005h2v5h-2z" fill="currentColor"></path></svg><svg class="dark-icon" viewbox="0 0 32 32" style="display:none;"><path d="M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z" fill="currentColor"></path></svg></button><!----></div></header><!--]--><div class="vp-sidebar-mask"></div><!--[--><aside class="vp-sidebar" vp-sidebar><nav class="vp-navbar-items" aria-label="site navigation"><!--[--><div class="vp-navbar-item"><a class="route-link auto-link" href="/" aria-label="主页"><!--[--><!--[--><!--]--><!--]-->主页<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/get-started.html" aria-label="配置教程"><!--[--><!--[--><!--]--><!--]-->配置教程<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/lua.html" aria-label="CMLeonOS Lua API 文档"><!--[--><!--[--><!--]--><!--]-->CMLeonOS Lua API 文档<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link route-link-active auto-link" href="/commands.html" aria-label="命令列表"><!--[--><!--[--><!--]--><!--]-->命令列表<!--[--><!--[--><!--]--><!--]--></a></div><!--]--></nav><!--[--><!--]--><ul class="vp-sidebar-items"><!--[--><li><p tabindex="0" class="vp-sidebar-item vp-sidebar-heading">命令列表 <!----></p><!----></li><!--]--></ul><!--[--><!--]--></aside><!--]--><!--[--><main class="vp-page"><!--[--><!--]--><div vp-content><!--[--><!--]--><div><h1 id="命令列表" tabindex="-1"><a class="header-anchor" href="#命令列表"><span>命令列表</span></a></h1><p>CMLeonOS 提供了丰富的命令行工具,以下是所有可用命令的详细说明。</p><h2 id="系统命令" tabindex="-1"><a class="header-anchor" href="#系统命令"><span>系统命令</span></a></h2><h3 id="echo" tabindex="-1"><a class="header-anchor" href="#echo"><span>echo</span></a></h3><p>输出文本到控制台。</p><p><strong>用法:</strong></p><div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh"><pre><code><span class="line"><span class="token builtin class-name">echo</span> <span class="token operator">&lt;</span>text<span class="token operator">&gt;</span></span>
@@ -179,7 +179,7 @@
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>示例:</strong></p><div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh"><pre><code><span class="line"><span class="token function">env</span></span>
<span class="line"><span class="token function">env</span> <span class="token environment constant">PATH</span></span>
<span class="line"><span class="token function">env</span> MYVAR hello</span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="注意事项" tabindex="-1"><a class="header-anchor" href="#注意事项"><span>注意事项</span></a></h2><ol><li>所有命令不区分大小写</li><li>使用 <code>help</code> 命令可以查看所有可用命令</li><li>使用 <code>help &lt;command&gt;</code> 可以查看特定命令的详细帮助</li><li>文件路径使用反斜杠 <code>\</code> 或正斜杠 <code>/</code> 均可</li><li>支持相对路径和绝对路径</li></ol></div><!--[--><!--]--></div><footer class="vp-page-meta"><!----><div class="vp-meta-item git-info"><div class="vp-meta-item last-updated"><span class="meta-item-label">最近更新:: </span><time class="meta-item-info" datetime="2026-02-06T08:18:30.000Z" data-allow-mismatch>2026/2/6 16:18</time></div><div class="vp-meta-item contributors"><span class="meta-item-label">Contributors: </span><span class="meta-item-info"><!--[--><!--[--><span class="contributor" title="email: testmod@qq.com">Leonmmcoset</span><!----><!--]--><!--]--></span></div></div></footer><!----><!--[--><!--]--></main><!--]--></div><!--[--><!----><!--]--><!--]--></div>
<script type="module" src="/assets/app-BITa06va.js" defer></script>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="注意事项" tabindex="-1"><a class="header-anchor" href="#注意事项"><span>注意事项</span></a></h2><ol><li>所有命令不区分大小写</li><li>使用 <code>help</code> 命令可以查看所有可用命令</li><li>使用 <code>help &lt;command&gt;</code> 可以查看特定命令的详细帮助</li><li>文件路径使用反斜杠 <code>\</code> 或正斜杠 <code>/</code> 均可</li><li>支持相对路径和绝对路径</li></ol></div><!--[--><!--]--></div><footer class="vp-page-meta"><!----><div class="vp-meta-item git-info"><div class="vp-meta-item last-updated"><span class="meta-item-label">最近更新:: </span><time class="meta-item-info" datetime="2026-02-06T09:30:12.000Z" data-allow-mismatch>2026/2/6 17:30</time></div><div class="vp-meta-item contributors"><span class="meta-item-label">Contributors: </span><span class="meta-item-info"><!--[--><!--[--><span class="contributor" title="email: testmod@qq.com">Leonmmcoset</span><!----><!--]--><!--]--></span></div></div></footer><!----><!--[--><!--]--></main><!--]--></div><!--[--><!----><!--]--><!--]--></div>
<script type="module" src="/assets/app-C2pVPwUc.js" defer></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -33,8 +33,8 @@
</script>
<title>CMLeonOS Lua API 文档 | CMLeonOS官方文档站</title><meta name="description" content="CMLeonOS是一个基于微内核架构的操作系统它的目标是提供一个简单、可靠、安全的操作系统环境。">
<link rel="preload" href="/assets/style-BmL0kmLr.css" as="style"><link rel="stylesheet" href="/assets/style-BmL0kmLr.css">
<link rel="modulepreload" href="/assets/app-BITa06va.js"><link rel="modulepreload" href="/assets/lua.html-DxDsLuB0.js">
<link rel="prefetch" href="/assets/commands.html-CJdMGWM7.js" as="script"><link rel="prefetch" href="/assets/get-started.html-D_vM18Nz.js" as="script"><link rel="prefetch" href="/assets/index.html-DS7rXIvH.js" as="script"><link rel="prefetch" href="/assets/404.html-B-2P5V78.js" as="script">
<link rel="modulepreload" href="/assets/app-C2pVPwUc.js"><link rel="modulepreload" href="/assets/lua.html-Cnr7xLDd.js">
<link rel="prefetch" href="/assets/commands.html-BVVm3joo.js" as="script"><link rel="prefetch" href="/assets/get-started.html-CVeJRoHk.js" as="script"><link rel="prefetch" href="/assets/index.html-MspKP7L1.js" as="script"><link rel="prefetch" href="/assets/404.html-BozFi7tE.js" as="script">
</head>
<body>
<div id="app"><!--[--><div class="vp-theme-container external-link-icon" vp-container><!--[--><header class="vp-navbar" vp-navbar><div class="vp-toggle-sidebar-button" title="toggle sidebar" aria-expanded="false" role="button" tabindex="0"><div class="icon" aria-hidden="true"><span></span><span></span><span></span></div></div><span><a class="route-link" href="/"><!----><span class="vp-site-name" aria-hidden="true">CMLeonOS官方文档站</span></a></span><div class="vp-navbar-items-wrapper" style=""><!--[--><!--]--><nav class="vp-navbar-items vp-hide-mobile" aria-label="site navigation"><!--[--><div class="vp-navbar-item"><a class="route-link auto-link" href="/" aria-label="主页"><!--[--><!--[--><!--]--><!--]-->主页<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/get-started.html" aria-label="配置教程"><!--[--><!--[--><!--]--><!--]-->配置教程<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link route-link-active auto-link" href="/lua.html" aria-label="CMLeonOS Lua API 文档"><!--[--><!--[--><!--]--><!--]-->CMLeonOS Lua API 文档<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/commands.html" aria-label="命令列表"><!--[--><!--[--><!--]--><!--]-->命令列表<!--[--><!--[--><!--]--><!--]--></a></div><!--]--></nav><!--[--><!--]--><button type="button" class="vp-toggle-color-mode-button" title="toggle color mode"><svg class="light-icon" viewbox="0 0 32 32" style=""><path d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6z" fill="currentColor"></path><path d="M5.394 6.813l1.414-1.415l3.506 3.506L8.9 10.318z" fill="currentColor"></path><path d="M2 15.005h5v2H2z" fill="currentColor"></path><path d="M5.394 25.197L8.9 21.691l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 25.005h2v5h-2z" fill="currentColor"></path><path d="M21.687 23.106l1.414-1.415l3.506 3.506l-1.414 1.414z" fill="currentColor"></path><path d="M25 15.005h5v2h-5z" fill="currentColor"></path><path d="M21.687 8.904l3.506-3.506l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 2.005h2v5h-2z" fill="currentColor"></path></svg><svg class="dark-icon" viewbox="0 0 32 32" style="display:none;"><path d="M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z" fill="currentColor"></path></svg></button><!----></div></header><!--]--><div class="vp-sidebar-mask"></div><!--[--><aside class="vp-sidebar" vp-sidebar><nav class="vp-navbar-items" aria-label="site navigation"><!--[--><div class="vp-navbar-item"><a class="route-link auto-link" href="/" aria-label="主页"><!--[--><!--[--><!--]--><!--]-->主页<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/get-started.html" aria-label="配置教程"><!--[--><!--[--><!--]--><!--]-->配置教程<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link route-link-active auto-link" href="/lua.html" aria-label="CMLeonOS Lua API 文档"><!--[--><!--[--><!--]--><!--]-->CMLeonOS Lua API 文档<!--[--><!--[--><!--]--><!--]--></a></div><div class="vp-navbar-item"><a class="route-link auto-link" href="/commands.html" aria-label="命令列表"><!--[--><!--[--><!--]--><!--]-->命令列表<!--[--><!--[--><!--]--><!--]--></a></div><!--]--></nav><!--[--><!--]--><ul class="vp-sidebar-items"><!--[--><li><p tabindex="0" class="vp-sidebar-item vp-sidebar-heading">CMLeonOS Lua API 文档 <!----></p><!----></li><!--]--></ul><!--[--><!--]--></aside><!--]--><!--[--><main class="vp-page"><!--[--><!--]--><div vp-content><!--[--><!--]--><div><h1 id="cmleonos-lua-api-文档" tabindex="-1"><a class="header-anchor" href="#cmleonos-lua-api-文档"><span>CMLeonOS Lua API 文档</span></a></h1><p>本文档记录了 CMLeonOS 中 Lua 支持的所有函数和库。</p><h2 id="基础库-base" tabindex="-1"><a class="header-anchor" href="#基础库-base"><span>基础库 (base)</span></a></h2><h3 id="assert-v-message" tabindex="-1"><a class="header-anchor" href="#assert-v-message"><span>assert(v [, message])</span></a></h3><p>如果 v 为 false 或 nil则抛出错误。可选参数 message 为错误信息。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line"><span class="token function">assert</span><span class="token punctuation">(</span><span class="token keyword">true</span><span class="token punctuation">,</span> <span class="token string">&quot;This should be true&quot;</span><span class="token punctuation">)</span></span>
@@ -205,7 +205,13 @@
<span class="line"><span class="token keyword">end</span></span>
<span class="line"><span class="token keyword">local</span> elapsed <span class="token operator">=</span> os<span class="token punctuation">.</span><span class="token function">timerstop</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token function">print</span><span class="token punctuation">(</span><span class="token string">&quot;Elapsed time:&quot;</span><span class="token punctuation">,</span> elapsed<span class="token punctuation">,</span> <span class="token string">&quot;seconds&quot;</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>注意</strong></p><ul><li>如果在未调用 <code>timerstart</code> 的情况下调用 <code>timerstop</code>,将返回 <code>nil</code></li><li>每次调用 <code>timerstop</code> 后,计时器会被重置</li><li>返回的时间单位为秒(浮点数)</li></ul><hr><h2 id="输入输出库-io" tabindex="-1"><a class="header-anchor" href="#输入输出库-io"><span>输入输出库 (io)</span></a></h2><h3 id="io-close-file" tabindex="-1"><a class="header-anchor" href="#io-close-file"><span>io.close(file)</span></a></h3><p>关闭文件。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line"><span class="token keyword">local</span> file <span class="token operator">=</span> io<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">&quot;test.txt&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;w&quot;</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>注意</strong></p><ul><li>如果在未调用 <code>timerstart</code> 的情况下调用 <code>timerstop</code>,将返回 <code>nil</code></li><li>每次调用 <code>timerstop</code> 后,计时器会被重置</li><li>返回的时间单位为秒(浮点数)</li></ul><h3 id="os-tui-drawbox-x-y-width-height-title-bordercolor-backgroundcolor" tabindex="-1"><a class="header-anchor" href="#os-tui-drawbox-x-y-width-height-title-bordercolor-backgroundcolor"><span>os.tui_drawbox(x, y, width, height, title, borderColor, backgroundColor)</span></a></h3><p>绘制带边框和标题的矩形框。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line">os<span class="token punctuation">.</span><span class="token function">tui_drawbox</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token string">&quot;Title&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;white&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;darkblue&quot;</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p><strong>参数</strong></p><ul><li><code>x</code> - 矩形框的左上角 X 坐标</li><li><code>y</code> - 矩形框的左上角 Y 坐标</li><li><code>width</code> - 矩形框的宽度</li><li><code>height</code> - 矩形框的高度</li><li><code>title</code> - 矩形框的标题(可选)</li><li><code>borderColor</code> - 边框颜色black, blue, cyan, darkblue, darkcyan, darkgray, darkgreen, darkmagenta, darkred, darkyellow, gray, green, magenta, red, white, yellow</li><li><code>backgroundColor</code> - 背景颜色(同上)</li></ul><h3 id="os-tui-drawtext-x-y-text-foregroundcolor-backgroundcolor" tabindex="-1"><a class="header-anchor" href="#os-tui-drawtext-x-y-text-foregroundcolor-backgroundcolor"><span>os.tui_drawtext(x, y, text, foregroundColor, backgroundColor)</span></a></h3><p>在指定位置绘制文本。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line">os<span class="token punctuation">.</span><span class="token function">tui_drawtext</span><span class="token punctuation">(</span><span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">&quot;Hello World!&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;yellow&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;black&quot;</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p><strong>参数</strong></p><ul><li><code>x</code> - 文本的 X 坐标</li><li><code>y</code> - 文本的 Y 坐标</li><li><code>text</code> - 要绘制的文本内容</li><li><code>foregroundColor</code> - 前景色(同上)</li><li><code>backgroundColor</code> - 背景色(同上)</li></ul><h3 id="os-tui-setcolor-foregroundcolor-backgroundcolor" tabindex="-1"><a class="header-anchor" href="#os-tui-setcolor-foregroundcolor-backgroundcolor"><span>os.tui_setcolor(foregroundColor, backgroundColor)</span></a></h3><p>设置前景色和背景色。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line">os<span class="token punctuation">.</span><span class="token function">tui_setcolor</span><span class="token punctuation">(</span><span class="token string">&quot;white&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;black&quot;</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p><strong>参数</strong></p><ul><li><code>foregroundColor</code> - 前景色black, blue, cyan, darkblue, darkcyan, darkgray, darkgreen, darkmagenta, darkred, darkyellow, gray, green, magenta, red, white, yellow</li><li><code>backgroundColor</code> - 背景色(同上)</li></ul><h3 id="os-tui-setcursor-x-y" tabindex="-1"><a class="header-anchor" href="#os-tui-setcursor-x-y"><span>os.tui_setcursor(x, y)</span></a></h3><p>设置光标位置。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line">os<span class="token punctuation">.</span><span class="token function">tui_setcursor</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p><strong>参数</strong></p><ul><li><code>x</code> - 光标的 X 坐标</li><li><code>y</code> - 光标的 Y 坐标</li></ul><h3 id="os-tui-clear" tabindex="-1"><a class="header-anchor" href="#os-tui-clear"><span>os.tui_clear()</span></a></h3><p>清屏。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line">os<span class="token punctuation">.</span><span class="token function">tui_clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><h3 id="os-tui-drawline-x-y-length-character-color" tabindex="-1"><a class="header-anchor" href="#os-tui-drawline-x-y-length-character-color"><span>os.tui_drawline(x, y, length, character, color)</span></a></h3><p>绘制水平线。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line">os<span class="token punctuation">.</span><span class="token function">tui_drawline</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token string">&quot;-&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;green&quot;</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p><strong>参数</strong></p><ul><li><code>x</code> - 线的起始 X 坐标</li><li><code>y</code> - 线的起始 Y 坐标</li><li><code>length</code> - 线的长度</li><li><code>character</code> - 用于绘制线的字符</li><li><code>color</code> - 线的颜色(同上)</li></ul><hr><h2 id="输入输出库-io" tabindex="-1"><a class="header-anchor" href="#输入输出库-io"><span>输入输出库 (io)</span></a></h2><h3 id="io-close-file" tabindex="-1"><a class="header-anchor" href="#io-close-file"><span>io.close(file)</span></a></h3><p>关闭文件。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line"><span class="token keyword">local</span> file <span class="token operator">=</span> io<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">&quot;test.txt&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;w&quot;</span><span class="token punctuation">)</span></span>
<span class="line">file<span class="token punctuation">:</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token string">&quot;Hello&quot;</span><span class="token punctuation">)</span></span>
<span class="line">io<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="io-flush" tabindex="-1"><a class="header-anchor" href="#io-flush"><span>io.flush()</span></a></h3><p>刷新所有打开文件的输出缓冲区。</p><div class="language-lua line-numbers-mode" data-highlighter="prismjs" data-ext="lua"><pre><code><span class="line">io<span class="token punctuation">.</span><span class="token function">flush</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
@@ -334,6 +340,6 @@
<span class="line"><span class="token function">print</span><span class="token punctuation">(</span><span class="token string">&quot;Encoded:&quot;</span><span class="token punctuation">,</span> encoded<span class="token punctuation">)</span></span>
<span class="line"><span class="token function">print</span><span class="token punctuation">(</span><span class="token string">&quot;Decoded:&quot;</span><span class="token punctuation">,</span> decoded<span class="token punctuation">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="注意事项" tabindex="-1"><a class="header-anchor" href="#注意事项"><span>注意事项</span></a></h2><ol><li><strong>交互模式</strong>:使用 <code>lua --shell</code> 进入交互式 Lua Shell</li><li><strong>错误处理</strong>:所有 Lua 执行错误都会被捕获并显示</li><li><strong>系统函数</strong><code>os</code> 库包含 CMLeonOS 特定的系统函数</li><li><strong>加密支持</strong>:支持 SHA256 和 Base64 编码/解码</li><li><strong>标准 Lua</strong>:完全兼容 Lua 5.1 标准</li></ol><h2 id="版本信息" tabindex="-1"><a class="header-anchor" href="#版本信息"><span>版本信息</span></a></h2><ul><li><strong>Lua 版本</strong>5.2</li><li><strong>CMLeonOS 版本</strong>:最新</li></ul></div><!--[--><!--]--></div><footer class="vp-page-meta"><!----><div class="vp-meta-item git-info"><div class="vp-meta-item last-updated"><span class="meta-item-label">最近更新:: </span><time class="meta-item-info" datetime="2026-02-05T05:15:17.000Z" data-allow-mismatch>2026/2/5 13:15</time></div><div class="vp-meta-item contributors"><span class="meta-item-label">Contributors: </span><span class="meta-item-info"><!--[--><!--[--><span class="contributor" title="email: testmod@qq.com">Leonmmcoset</span><!----><!--]--><!--]--></span></div></div></footer><!----><!--[--><!--]--></main><!--]--></div><!--[--><!----><!--]--><!--]--></div>
<script type="module" src="/assets/app-BITa06va.js" defer></script>
<script type="module" src="/assets/app-C2pVPwUc.js" defer></script>
</body>
</html>

View File

@@ -721,6 +721,79 @@ print("Elapsed time:", elapsed, "seconds")
- 每次调用 `timerstop` 后,计时器会被重置
- 返回的时间单位为秒(浮点数)
### os.tui_drawbox(x, y, width, height, title, borderColor, backgroundColor)
绘制带边框和标题的矩形框。
```lua
os.tui_drawbox(10, 5, 40, 10, "Title", "white", "darkblue")
```
**参数**
- `x` - 矩形框的左上角 X 坐标
- `y` - 矩形框的左上角 Y 坐标
- `width` - 矩形框的宽度
- `height` - 矩形框的高度
- `title` - 矩形框的标题(可选)
- `borderColor` - 边框颜色black, blue, cyan, darkblue, darkcyan, darkgray, darkgreen, darkmagenta, darkred, darkyellow, gray, green, magenta, red, white, yellow
- `backgroundColor` - 背景颜色(同上)
### os.tui_drawtext(x, y, text, foregroundColor, backgroundColor)
在指定位置绘制文本。
```lua
os.tui_drawtext(15, 8, "Hello World!", "yellow", "black")
```
**参数**
- `x` - 文本的 X 坐标
- `y` - 文本的 Y 坐标
- `text` - 要绘制的文本内容
- `foregroundColor` - 前景色(同上)
- `backgroundColor` - 背景色(同上)
### os.tui_setcolor(foregroundColor, backgroundColor)
设置前景色和背景色。
```lua
os.tui_setcolor("white", "black")
```
**参数**
- `foregroundColor` - 前景色black, blue, cyan, darkblue, darkcyan, darkgray, darkgreen, darkmagenta, darkred, darkyellow, gray, green, magenta, red, white, yellow
- `backgroundColor` - 背景色(同上)
### os.tui_setcursor(x, y)
设置光标位置。
```lua
os.tui_setcursor(20, 10)
```
**参数**
- `x` - 光标的 X 坐标
- `y` - 光标的 Y 坐标
### os.tui_clear()
清屏。
```lua
os.tui_clear()
```
### os.tui_drawline(x, y, length, character, color)
绘制水平线。
```lua
os.tui_drawline(10, 15, 30, "-", "green")
```
**参数**
- `x` - 线的起始 X 坐标
- `y` - 线的起始 Y 坐标
- `length` - 线的长度
- `character` - 用于绘制线的字符
- `color` - 线的颜色(同上)
---
## 输入输出库 (io)

View File

@@ -4,6 +4,7 @@ namespace UniLua
using System.Diagnostics;
using System;
using CMLeonOS;
using CMLeonOS.UI;
using Sys = Cosmos.System;
using System.Threading;
@@ -38,10 +39,17 @@ namespace UniLua
new NameFuncPair("base64decrypt", OS_Base64Decrypt),
new NameFuncPair("timerstart", OS_TimerStart),
new NameFuncPair("timerstop", OS_TimerStop),
new NameFuncPair("tui_drawbox", OS_TUIDrawBox),
new NameFuncPair("tui_drawtext", OS_TUIDrawText),
new NameFuncPair("tui_setcolor", OS_TUISetColor),
new NameFuncPair("tui_setcursor", OS_TUISetCursor),
new NameFuncPair("tui_clear", OS_TUIClear),
new NameFuncPair("tui_drawline", OS_TUIDrawLine),
#endif
};
lua.L_NewLib( define );
return 1;
}
@@ -231,6 +239,118 @@ namespace UniLua
_timerStartTime = null;
return 1;
}
private static int OS_TUIDrawBox(ILuaState lua)
{
int x = (int)lua.L_CheckNumber(1);
int y = (int)lua.L_CheckNumber(2);
int width = (int)lua.L_CheckNumber(3);
int height = (int)lua.L_CheckNumber(4);
string title = lua.L_CheckString(5);
string borderColor = lua.L_CheckString(6);
string backgroundColor = lua.L_CheckString(7);
ConsoleColor borderColorEnum = ParseColor(borderColor);
ConsoleColor backgroundColorEnum = ParseColor(backgroundColor);
var rect = new Rect(x, y, width, height);
TUIHelper.SetColors(borderColorEnum, backgroundColorEnum);
TUIHelper.DrawBox(rect, title, borderColorEnum);
lua.PushBoolean(true);
return 1;
}
private static int OS_TUIDrawText(ILuaState lua)
{
int x = (int)lua.L_CheckNumber(1);
int y = (int)lua.L_CheckNumber(2);
string text = lua.L_CheckString(3);
string foregroundColor = lua.L_CheckString(4);
string backgroundColor = lua.L_CheckString(5);
ConsoleColor foregroundColorEnum = ParseColor(foregroundColor);
ConsoleColor backgroundColorEnum = ParseColor(backgroundColor);
TUIHelper.SetColors(foregroundColorEnum, backgroundColorEnum);
Console.SetCursorPosition(x, y);
Console.Write(text);
lua.PushBoolean(true);
return 1;
}
private static int OS_TUISetColor(ILuaState lua)
{
string foregroundColor = lua.L_CheckString(1);
string backgroundColor = lua.L_CheckString(2);
ConsoleColor foregroundColorEnum = ParseColor(foregroundColor);
ConsoleColor backgroundColorEnum = ParseColor(backgroundColor);
TUIHelper.SetColors(foregroundColorEnum, backgroundColorEnum);
lua.PushBoolean(true);
return 1;
}
private static int OS_TUISetCursor(ILuaState lua)
{
int x = (int)lua.L_CheckNumber(1);
int y = (int)lua.L_CheckNumber(2);
Console.SetCursorPosition(x, y);
lua.PushBoolean(true);
return 1;
}
private static int OS_TUIClear(ILuaState lua)
{
Console.Clear();
lua.PushBoolean(true);
return 1;
}
private static int OS_TUIDrawLine(ILuaState lua)
{
int x = (int)lua.L_CheckNumber(1);
int y = (int)lua.L_CheckNumber(2);
int length = (int)lua.L_CheckNumber(3);
char character = lua.L_CheckString(4)[0];
string color = lua.L_CheckString(5);
ConsoleColor colorEnum = ParseColor(color);
TUIHelper.SetColors(colorEnum, ConsoleColor.Black);
Console.SetCursorPosition(x, y);
for (int i = 0; i < length; i++)
{
Console.Write(character);
}
lua.PushBoolean(true);
return 1;
}
private static ConsoleColor ParseColor(string colorName)
{
switch (colorName.ToLower())
{
case "black": return ConsoleColor.Black;
case "blue": return ConsoleColor.Blue;
case "cyan": return ConsoleColor.Cyan;
case "darkblue": return ConsoleColor.DarkBlue;
case "darkcyan": return ConsoleColor.DarkCyan;
case "darkgray": return ConsoleColor.DarkGray;
case "darkgreen": return ConsoleColor.DarkGreen;
case "darkmagenta": return ConsoleColor.DarkMagenta;
case "darkred": return ConsoleColor.DarkRed;
case "darkyellow": return ConsoleColor.DarkYellow;
case "gray": return ConsoleColor.Gray;
case "green": return ConsoleColor.Green;
case "magenta": return ConsoleColor.Magenta;
case "red": return ConsoleColor.Red;
case "white": return ConsoleColor.White;
case "yellow": return ConsoleColor.Yellow;
default: return ConsoleColor.White;
}
}
#endif
}
}

View File

@@ -27,6 +27,11 @@ namespace CMLeonOS.Commands
menu.Items.Add(new MenuItem("Progress Bar Demo", () => ShowProgressBarDemo()));
menu.Items.Add(new MenuItem("Tab Control Demo", () => ShowTabControlDemo()));
menu.Items.Add(new MenuItem("Menu Demo", () => ShowMenuDemo()));
menu.Items.Add(new MenuItem("ListBox Demo", () => ShowListBoxDemo()));
menu.Items.Add(new MenuItem("CheckBox Demo", () => ShowCheckBoxDemo()));
menu.Items.Add(new MenuItem("RadioButton Demo", () => ShowRadioButtonDemo()));
menu.Items.Add(new MenuItem("TreeView Demo", () => ShowTreeViewDemo()));
menu.Items.Add(new MenuItem("ScrollBar Demo", () => ShowScrollBarDemo()));
menu.Items.Add(new MenuItem("Exit", () => global::System.Environment.Exit(0)));
menu.Render();
@@ -365,5 +370,315 @@ namespace CMLeonOS.Commands
}
}
}
private static void ShowListBoxDemo()
{
global::System.Console.Clear();
var statusBar = new StatusBar(new Rect(0, 24, 80, 1));
statusBar.Items.Add(new StatusBarItem("Use UP/DOWN to navigate, SPACE to select, ESC to return"));
statusBar.Render();
var listBox = new ListBox(new Rect(10, 5, 60, 15));
listBox.Items.Add("Item 1: Basic functionality");
listBox.Items.Add("Item 2: Advanced features");
listBox.Items.Add("Item 3: Settings");
listBox.Items.Add("Item 4: Help");
listBox.Items.Add("Item 5: About");
listBox.Items.Add("Item 6: Documentation");
listBox.Items.Add("Item 7: Configuration");
listBox.Items.Add("Item 8: System info");
listBox.Items.Add("Item 9: Network settings");
listBox.Items.Add("Item 10: User management");
listBox.MultiSelect = true;
listBox.Render();
bool demoRunning = true;
while (demoRunning)
{
var key = global::System.Console.ReadKey(true);
if (key.Key == global::System.ConsoleKey.Escape)
{
demoRunning = false;
}
else if (listBox.HandleKey(key))
{
listBox.Render();
}
}
}
private static void ShowCheckBoxDemo()
{
global::System.Console.Clear();
var statusBar = new StatusBar(new Rect(0, 24, 80, 1));
statusBar.Items.Add(new StatusBarItem("Use UP/DOWN to navigate, SPACE to toggle, ESC to return"));
statusBar.Render();
var checkBox1 = new CheckBox(new Point(10, 8), "Enable feature 1");
checkBox1.IsChecked = true;
checkBox1.IsFocused = true;
var checkBox2 = new CheckBox(new Point(10, 10), "Enable feature 2");
checkBox2.IsChecked = false;
var checkBox3 = new CheckBox(new Point(10, 12), "Enable feature 3");
checkBox3.IsChecked = false;
var checkBox4 = new CheckBox(new Point(10, 14), "Enable feature 4");
checkBox4.IsChecked = false;
checkBox1.Render();
checkBox2.Render();
checkBox3.Render();
checkBox4.Render();
int focusedCheckBox = 0;
bool demoRunning = true;
while (demoRunning)
{
var key = global::System.Console.ReadKey(true);
if (key.Key == global::System.ConsoleKey.Escape)
{
demoRunning = false;
}
else if (key.Key == global::System.ConsoleKey.UpArrow)
{
checkBox1.IsFocused = false;
checkBox2.IsFocused = false;
checkBox3.IsFocused = false;
checkBox4.IsFocused = false;
focusedCheckBox = (focusedCheckBox - 1 + 4) % 4;
if (focusedCheckBox == 0) checkBox1.IsFocused = true;
if (focusedCheckBox == 1) checkBox2.IsFocused = true;
if (focusedCheckBox == 2) checkBox3.IsFocused = true;
if (focusedCheckBox == 3) checkBox4.IsFocused = true;
}
else if (key.Key == global::System.ConsoleKey.DownArrow)
{
checkBox1.IsFocused = false;
checkBox2.IsFocused = false;
checkBox3.IsFocused = false;
checkBox4.IsFocused = false;
focusedCheckBox = (focusedCheckBox + 1) % 4;
if (focusedCheckBox == 0) checkBox1.IsFocused = true;
if (focusedCheckBox == 1) checkBox2.IsFocused = true;
if (focusedCheckBox == 2) checkBox3.IsFocused = true;
if (focusedCheckBox == 3) checkBox4.IsFocused = true;
}
else if (key.Key == global::System.ConsoleKey.Enter || key.Key == global::System.ConsoleKey.Spacebar)
{
if (focusedCheckBox == 0) checkBox1.IsChecked = !checkBox1.IsChecked;
if (focusedCheckBox == 1) checkBox2.IsChecked = !checkBox2.IsChecked;
if (focusedCheckBox == 2) checkBox3.IsChecked = !checkBox3.IsChecked;
if (focusedCheckBox == 3) checkBox4.IsChecked = !checkBox4.IsChecked;
}
checkBox1.Render();
checkBox2.Render();
checkBox3.Render();
checkBox4.Render();
}
}
private static void ShowRadioButtonDemo()
{
global::System.Console.Clear();
var statusBar = new StatusBar(new Rect(0, 24, 80, 1));
statusBar.Items.Add(new StatusBarItem("Use UP/DOWN to navigate, SPACE to select, ESC to return"));
statusBar.Render();
var radioButton1 = new RadioButton(new Point(10, 8), "Option 1");
radioButton1.IsChecked = true;
radioButton1.IsFocused = true;
radioButton1.GroupName = "group1";
var radioButton2 = new RadioButton(new Point(10, 10), "Option 2");
radioButton2.IsChecked = false;
radioButton2.GroupName = "group1";
var radioButton3 = new RadioButton(new Point(10, 12), "Option 3");
radioButton3.IsChecked = false;
radioButton3.GroupName = "group1";
var radioButton4 = new RadioButton(new Point(10, 14), "Option 4");
radioButton4.IsChecked = false;
radioButton4.GroupName = "group1";
radioButton1.Render();
radioButton2.Render();
radioButton3.Render();
radioButton4.Render();
int focusedRadioButton = 0;
bool demoRunning = true;
while (demoRunning)
{
var key = global::System.Console.ReadKey(true);
if (key.Key == global::System.ConsoleKey.Escape)
{
demoRunning = false;
}
else if (key.Key == global::System.ConsoleKey.UpArrow)
{
radioButton1.IsFocused = false;
radioButton2.IsFocused = false;
radioButton3.IsFocused = false;
radioButton4.IsFocused = false;
focusedRadioButton = (focusedRadioButton - 1 + 4) % 4;
if (focusedRadioButton == 0) radioButton1.IsFocused = true;
if (focusedRadioButton == 1) radioButton2.IsFocused = true;
if (focusedRadioButton == 2) radioButton3.IsFocused = true;
if (focusedRadioButton == 3) radioButton4.IsFocused = true;
}
else if (key.Key == global::System.ConsoleKey.DownArrow)
{
radioButton1.IsFocused = false;
radioButton2.IsFocused = false;
radioButton3.IsFocused = false;
radioButton4.IsFocused = false;
focusedRadioButton = (focusedRadioButton + 1) % 4;
if (focusedRadioButton == 0) radioButton1.IsFocused = true;
if (focusedRadioButton == 1) radioButton2.IsFocused = true;
if (focusedRadioButton == 2) radioButton3.IsFocused = true;
if (focusedRadioButton == 3) radioButton4.IsFocused = true;
}
else if (key.Key == global::System.ConsoleKey.Enter || key.Key == global::System.ConsoleKey.Spacebar)
{
if (focusedRadioButton == 0) radioButton1.IsChecked = true;
if (focusedRadioButton == 1) radioButton2.IsChecked = true;
if (focusedRadioButton == 2) radioButton3.IsChecked = true;
if (focusedRadioButton == 3) radioButton4.IsChecked = true;
}
radioButton1.Render();
radioButton2.Render();
radioButton3.Render();
radioButton4.Render();
}
}
private static void ShowTreeViewDemo()
{
global::System.Console.Clear();
var statusBar = new StatusBar(new Rect(0, 24, 80, 1));
statusBar.Items.Add(new StatusBarItem("Use UP/DOWN to navigate, ENTER/SPACE to expand/collapse, ESC to return"));
statusBar.Render();
var treeView = new TreeView(new Rect(5, 5, 70, 15));
treeView.Root = new TreeViewNode { Text = "Root" };
var child1 = new TreeViewNode { Text = "Folder 1", Level = 1, Parent = treeView.Root };
var child2 = new TreeViewNode { Text = "Folder 2", Level = 1, Parent = treeView.Root };
var child3 = new TreeViewNode { Text = "File 1", Level = 2, Parent = child1 };
var child4 = new TreeViewNode { Text = "File 2", Level = 2, Parent = child1 };
var child5 = new TreeViewNode { Text = "File 3", Level = 2, Parent = child2 };
child1.Children.Add(child3);
child1.Children.Add(child4);
child2.Children.Add(child5);
treeView.Root.Children.Add(child1);
treeView.Root.Children.Add(child2);
treeView.Render();
bool demoRunning = true;
while (demoRunning)
{
var key = global::System.Console.ReadKey(true);
if (key.Key == global::System.ConsoleKey.Escape)
{
demoRunning = false;
}
else if (treeView.HandleKey(key))
{
treeView.Render();
}
}
}
private static void ShowScrollBarDemo()
{
global::System.Console.Clear();
var statusBar = new StatusBar(new Rect(0, 24, 80, 1));
statusBar.Items.Add(new StatusBarItem("Use UP/DOWN or LEFT/RIGHT to adjust, ESC to return"));
statusBar.Render();
var scrollBar1 = new ScrollBar(new Point(15, 10), 10);
scrollBar1.MaxValue = 100;
scrollBar1.Value = 50;
scrollBar1.IsVertical = true;
var scrollBar2 = new ScrollBar(new Point(40, 10), 30);
scrollBar2.MaxValue = 100;
scrollBar2.Value = 30;
scrollBar2.IsVertical = false;
var scrollBar3 = new ScrollBar(new Point(15, 15), 10);
scrollBar3.MaxValue = 50;
scrollBar3.Value = 25;
scrollBar3.IsVertical = true;
var scrollBar4 = new ScrollBar(new Point(40, 15), 30);
scrollBar4.MaxValue = 50;
scrollBar4.Value = 15;
scrollBar4.IsVertical = false;
var label1 = new Label(new Point(15, 8), "Vertical ScrollBar:");
var label2 = new Label(new Point(40, 8), "Horizontal ScrollBar:");
var label3 = new Label(new Point(15, 13), "Small Vertical:");
var label4 = new Label(new Point(40, 13), "Small Horizontal:");
label1.Render();
label2.Render();
label3.Render();
label4.Render();
scrollBar1.Render();
scrollBar2.Render();
scrollBar3.Render();
scrollBar4.Render();
int focusedScrollBar = 0;
bool demoRunning = true;
while (demoRunning)
{
var key = global::System.Console.ReadKey(true);
if (key.Key == global::System.ConsoleKey.Escape)
{
demoRunning = false;
}
else if (key.Key == global::System.ConsoleKey.UpArrow || key.Key == global::System.ConsoleKey.DownArrow)
{
if (focusedScrollBar == 0 && scrollBar1.HandleKey(key)) scrollBar1.Render();
if (focusedScrollBar == 1 && scrollBar2.HandleKey(key)) scrollBar2.Render();
if (focusedScrollBar == 2 && scrollBar3.HandleKey(key)) scrollBar3.Render();
if (focusedScrollBar == 3 && scrollBar4.HandleKey(key)) scrollBar4.Render();
}
else if (key.Key == global::System.ConsoleKey.LeftArrow || key.Key == global::System.ConsoleKey.RightArrow)
{
if (focusedScrollBar == 0 && scrollBar1.HandleKey(key)) scrollBar1.Render();
if (focusedScrollBar == 1 && scrollBar2.HandleKey(key)) scrollBar2.Render();
if (focusedScrollBar == 2 && scrollBar3.HandleKey(key)) scrollBar3.Render();
if (focusedScrollBar == 3 && scrollBar4.HandleKey(key)) scrollBar4.Render();
}
else if (key.Key == global::System.ConsoleKey.Tab)
{
focusedScrollBar = (focusedScrollBar + 1) % 4;
}
}
}
}
}