Compare commits

...

3 Commits

Author SHA1 Message Date
Leonmmcoset
ad2ed876d2 lua快捷运行 2026-02-08 01:53:59 +08:00
Leonmmcoset
4abc6e96cf 统一Usage 2026-02-08 01:22:08 +08:00
Leonmmcoset
85fa99f7bd 修改字体 2026-02-08 00:13:16 +08:00
14 changed files with 556 additions and 35 deletions

2
Build.bat Normal file
View File

@@ -0,0 +1,2 @@
"D:\Microsoft Visual Studio\18\Community\MSBuild\Current\Bin\amd64\MSBuild.exe" "CMLeonOS.csproj" /t:Build /p:Configuration=Fixed_Release /p:Platform=x64
@REM "C:\Program Files (x86)\VMware\VMware Workstation\vmplayer.exe" "C:\Users\leon\AppData\Roaming\Cosmos User Kit\Build\VMware\Workstation\Cosmos.vmx"

View File

@@ -30,7 +30,37 @@
<VBEResolution>800x600x32</VBEResolution>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<WarningLevel>8</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<WarningLevel>8</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<WarningLevel>8</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<WarningLevel>8</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Fixed_Release|AnyCPU'">
<WarningLevel>8</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Fixed_Release|x64'">
<WarningLevel>8</WarningLevel>
</PropertyGroup>
<ItemGroup>
<None Remove="font.psf" />
<None Remove="Solarize.12x29.psf" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="font.psf" />
<EmbeddedResource Include="Wallpapers\wallpaper.bmp" />
</ItemGroup>

View File

@@ -1,19 +1,23 @@
using CMLeonOS.Logger;
using CMLeonOS.Settings;
using Cosmos.HAL;
using Cosmos.HAL.BlockDevice;
using Cosmos.HAL.Drivers.Video;
using Cosmos.System.FileSystem;
using Cosmos.System.FileSystem.FAT;
using Cosmos.System.FileSystem.VFS;
using Cosmos.System.Graphics;
using Cosmos.System.Graphics.Fonts;
using Cosmos.System.Network.Config;
using Cosmos.System.Network.IPv4.UDP.DHCP;
using Cosmos.HAL.BlockDevice;
using Cosmos.System.Network.IPv4;
using Cosmos.System.Network.IPv4.UDP.DHCP;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection.Metadata.Ecma335;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Sys = Cosmos.System;
using CMLeonOS.Logger;
using CMLeonOS.Settings;
namespace CMLeonOS
{
@@ -31,9 +35,31 @@ namespace CMLeonOS
public static Cosmos.HAL.NetworkDevice NetworkDevice = null;
public static string IPAddress = "Unknown";
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.font.psf")]
public static readonly byte[] file;
protected override void BeforeRun()
{
// 我认了,我用默认字体
// try
// {
// PCScreenFont screenFont = PCScreenFont.LoadFont(file);
// VGAScreen.SetFont(screenFont.CreateVGAFont(), screenFont.Height);
// VGAScreen.SetGraphicsMode(VGADriver.ScreenSize.Size720x480, ColorDepth.ColorDepth32);
// }
// catch (Exception ex)
// {
// 我不认我试着转换成Base64
// 我认了
PCScreenFont defaultFont = PCScreenFont.Default;
VGAScreen.SetFont(defaultFont.CreateVGAFont(), defaultFont.Height);
// Console.WriteLine($"{defaultFont.Height}");
// Console.WriteLine($"{defaultFont.Width}");
// VGAScreen.SetGraphicsMode(VGADriver.ScreenSize.Size720x480, ColorDepth.ColorDepth32);
// Console.WriteLine($"Error loading font: {ex.Message}");
// }
Console.WriteLine("Kernel load done!");
Console.WriteLine(@"-------------------------------------------------");
Console.WriteLine(@" ____ __ __ _ ___ ____ ");
@@ -73,6 +99,14 @@ namespace CMLeonOS
_logger.Info("Kernel", "Created system folder at 0:\\system");
}
// 检查并创建apps文件夹
string appsFolderPath = @"0:\apps";
if (!System.IO.Directory.Exists(appsFolderPath))
{
System.IO.Directory.CreateDirectory(appsFolderPath);
_logger.Info("Kernel", "Created apps folder at 0:\\apps");
}
// 初始化用户系统
_logger.Info("Kernel", "Initializing user system");
userSystem = new UserSystem();

BIN
font.psf Normal file

Binary file not shown.

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CMLeonOS;
namespace CMLeonOS.Commands.Environment
{
@@ -11,7 +13,41 @@ namespace CMLeonOS.Commands.Environment
if (parts.Length == 0)
{
envManager.ListVariables();
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "list",
Description = "List all environment variables",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "see <varname>",
Description = "View environment variable value",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "add <varname> <value>",
Description = "Add environment variable",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "change <varname> <value>",
Description = "Change environment variable",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "delete <varname>",
Description = "Delete environment variable",
IsOptional = false
}
};
showError(UsageGenerator.GenerateUsage("env", commandInfos));
return;
}
@@ -39,7 +75,7 @@ namespace CMLeonOS.Commands.Environment
else
{
showError("Error: Please specify variable name");
showError("Usage: env see <varname>");
showError(UsageGenerator.GenerateSimpleUsage("env", "see <varname>"));
}
break;
case "add":
@@ -60,7 +96,7 @@ namespace CMLeonOS.Commands.Environment
else
{
showError("Error: Please specify variable name and value");
showError("Usage: env add <varname> <value>");
showError(UsageGenerator.GenerateSimpleUsage("env", "add <varname> <value>"));
}
break;
case "change":
@@ -81,7 +117,7 @@ namespace CMLeonOS.Commands.Environment
else
{
showError("Error: Please specify variable name and value");
showError("Usage: env change <varname> <value>");
showError(UsageGenerator.GenerateSimpleUsage("env", "change <varname> <value>"));
}
break;
case "delete":
@@ -101,12 +137,46 @@ namespace CMLeonOS.Commands.Environment
else
{
showError("Error: Please specify variable name");
showError("Usage: env delete <varname>");
showError(UsageGenerator.GenerateSimpleUsage("env", "delete <varname>"));
}
break;
default:
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "list",
Description = "List all environment variables",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "see <varname>",
Description = "View environment variable value",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "add <varname> <value>",
Description = "Add environment variable",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "change <varname> <value>",
Description = "Change environment variable",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "delete <varname>",
Description = "Delete environment variable",
IsOptional = false
}
};
showError("Error: Invalid env command");
showError("Usage: env [list] | env see <varname> | env add <varname> <value> | env change <varname> <value> | env delete <varname>");
showError(UsageGenerator.GenerateUsage("env", commandInfos));
break;
}
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using CMLeonOS;
namespace CMLeonOS.Commands.FileSystem
{
@@ -8,7 +10,24 @@ namespace CMLeonOS.Commands.FileSystem
{
if (string.IsNullOrEmpty(args))
{
showError("Please specify a file name");
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "<file>",
Description = "Delete file",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "<file> -norisk",
Description = "Delete file in sys folder without confirmation",
IsOptional = false
}
};
showError(UsageGenerator.GenerateUsage("rm", commandInfos));
return;
}
else
{
@@ -29,7 +48,7 @@ namespace CMLeonOS.Commands.FileSystem
if (!hasNorisk)
{
showError("Cannot delete files in sys folder without -norisk parameter");
showError("Usage: rm <file> -norisk");
showError(UsageGenerator.GenerateSimpleUsage("rm", "<file> -norisk"));
}
else
{

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using CMLeonOS;
namespace CMLeonOS.Commands.Script
{
@@ -9,8 +11,17 @@ namespace CMLeonOS.Commands.Script
{
if (string.IsNullOrEmpty(args))
{
showError("Error: Please specify file name");
showError("Usage: branswe <filename>");
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "<filename>",
Description = "Execute Branswe file",
IsOptional = false
}
};
showError(UsageGenerator.GenerateUsage("branswe", commandInfos));
return;
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using CMLeonOS;
namespace CMLeonOS.Commands.Script
{
@@ -9,7 +11,17 @@ namespace CMLeonOS.Commands.Script
{
if (string.IsNullOrEmpty(args))
{
showError("Usage: com <filename.cm>");
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "<filename.cm>",
Description = "Execute command file",
IsOptional = false
}
};
showError(UsageGenerator.GenerateUsage("com", commandInfos));
return;
}

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using UniLua;
using CMLeonOS;
namespace CMLeonOS.Commands.Script
{
@@ -12,8 +14,23 @@ namespace CMLeonOS.Commands.Script
if (parts.Length == 0)
{
showError("Error: Please specify Lua script file or use --shell for interactive mode");
showError("Usage: lua <file> or lua --shell");
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "<file>",
Description = "Execute Lua script file",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "--shell",
Description = "Enter Lua interactive shell",
IsOptional = false
}
};
showError(UsageGenerator.GenerateUsage("lua", commandInfos));
return;
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using CMLeonOS;
namespace CMLeonOS.Commands.User
{
@@ -8,7 +10,17 @@ namespace CMLeonOS.Commands.User
{
if (string.IsNullOrEmpty(args))
{
showError("Usage: hostname <new_hostname>");
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "<new_hostname>",
Description = "Set new hostname",
IsOptional = false
}
};
showError(UsageGenerator.GenerateUsage("hostname", commandInfos));
return;
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using CMLeonOS;
namespace CMLeonOS.Commands.User
{
@@ -15,19 +17,41 @@ namespace CMLeonOS.Commands.User
{
if (userSystem == null || userSystem.CurrentLoggedInUser == null || !userSystem.CurrentLoggedInUser.IsAdmin)
{
showError("Error: Only administrators can use the user command.");
showError("Error: Only administrators can use this command.");
return;
}
if (string.IsNullOrEmpty(args))
{
showError("Error: Please specify a user command");
showError("Please specify a user command");
showError("user <add|delete> [args]");
showError(" user add admin <username> <password> - Add admin user");
showError(" user add user <username> <password> - Add regular user");
showError(" user delete <username> - Delete user");
showError(" user list - List all users");
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "add admin <username> <password>",
Description = "Add admin user",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "add user <username> <password>",
Description = "Add regular user",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "delete <username>",
Description = "Delete user",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "list",
Description = "List all users",
IsOptional = false
}
};
showError(UsageGenerator.GenerateUsage("user", commandInfos));
return;
}
@@ -35,7 +59,7 @@ namespace CMLeonOS.Commands.User
if (parts.Length < 1)
{
showError("Error: Please specify a user command");
showError("Usage: user <add|delete> [args]");
showError(UsageGenerator.GenerateSimpleUsage("user", "<add|delete> [args]"));
return;
}
@@ -46,8 +70,8 @@ namespace CMLeonOS.Commands.User
if (parts.Length < 4)
{
showError("Error: Please specify user type and username and password");
showError("Usage: user add admin <username> <password>");
showError("Usage: user add user <username> <password>");
showError(UsageGenerator.GenerateSimpleUsage("user", "add admin <username> <password>"));
showError(UsageGenerator.GenerateSimpleUsage("user", "add user <username> <password>"));
return;
}
@@ -63,7 +87,7 @@ namespace CMLeonOS.Commands.User
if (parts.Length < 2)
{
showError("Error: Please specify username");
showError("Usage: user delete <username>");
showError(UsageGenerator.GenerateSimpleUsage("user", "delete <username>"));
return;
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using CMLeonOS;
namespace CMLeonOS.Commands.Utility
{
@@ -10,8 +12,23 @@ namespace CMLeonOS.Commands.Utility
if (parts.Length == 0)
{
showError("Error: Please specify subcommand");
showError("Usage: base64 encrypt <text> | base64 decrypt <text>");
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "encrypt <text>",
Description = "Encode text to Base64",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "decrypt <text>",
Description = "Decode Base64 to text",
IsOptional = false
}
};
showError(UsageGenerator.GenerateCompactUsage("base64", commandInfos));
return;
}
@@ -19,15 +36,31 @@ namespace CMLeonOS.Commands.Utility
if (subcommand != "encrypt" && subcommand != "decrypt")
{
var commandInfos = new List<UsageGenerator.CommandInfo>
{
new UsageGenerator.CommandInfo
{
Command = "encrypt <text>",
Description = "Encode text to Base64",
IsOptional = false
},
new UsageGenerator.CommandInfo
{
Command = "decrypt <text>",
Description = "Decode Base64 to text",
IsOptional = false
}
};
showError("Error: Invalid subcommand");
showError("Usage: base64 encrypt <text> | base64 decrypt <text>");
showError(UsageGenerator.GenerateCompactUsage("base64", commandInfos));
return;
}
if (parts.Length < 2)
{
showError("Error: Please specify text to process");
showError($"Usage: base64 {subcommand} <text>");
showError(UsageGenerator.GenerateSimpleUsage("base64", $"{subcommand} <text>"));
return;
}

View File

@@ -19,7 +19,6 @@ using Cosmos.Core.Memory;
using UniLua;
using Cosmos.HAL;
using CMLeonOS.Commands;
namespace CMLeonOS
{
public class Shell
@@ -408,6 +407,22 @@ namespace CMLeonOS
string expandedCommand = command;
string expandedArgs = args;
if (command.StartsWith(":"))
{
string appName = command.Substring(1);
string appPath = "0:\\apps\\" + appName + ".lua";
if (System.IO.File.Exists(appPath))
{
Commands.Script.LuaCommand.ExecuteLuaScript(appPath, fileSystem, this, ShowError, ShowWarning);
}
else
{
ShowError($"App not found: {appName}");
}
return;
}
string aliasValue = Commands.AliasCommand.GetAlias(command);
if (aliasValue != null)
{

242
shell/UsageGenerator.cs Normal file
View File

@@ -0,0 +1,242 @@
using System;
using System.Collections.Generic;
namespace CMLeonOS
{
public class UsageGenerator
{
public class CommandInfo
{
public string Command { get; set; }
public List<SubCommandInfo> SubCommands { get; set; } = new List<SubCommandInfo>();
public string Description { get; set; }
public bool IsOptional { get; set; }
}
public class SubCommandInfo
{
public string Command { get; set; }
public string Description { get; set; }
public bool IsOptional { get; set; }
}
public static string GenerateUsage(string commandName, List<CommandInfo> commandInfos)
{
List<string> lines = new List<string>();
lines.Add("Usage: " + commandName + " [subcommand] [args]");
lines.Add("");
foreach (var commandInfo in commandInfos)
{
string cmdDisplay = commandInfo.IsOptional ? "[" + commandInfo.Command + "]" : commandInfo.Command;
string commandLine = " " + commandName + " " + cmdDisplay;
if (!string.IsNullOrEmpty(commandInfo.Description))
{
int padding = 50 - commandLine.Length;
if (padding < 1) padding = 1;
commandLine += new string(' ', padding) + "- " + commandInfo.Description;
}
lines.Add(commandLine);
if (commandInfo.SubCommands.Count > 0)
{
foreach (var subCommand in commandInfo.SubCommands)
{
string subCmdDisplay = subCommand.IsOptional ? "[" + subCommand.Command + "]" : subCommand.Command;
string subCommandLine = " " + commandName + " " + commandInfo.Command + " " + subCmdDisplay;
if (!string.IsNullOrEmpty(subCommand.Description))
{
int padding = 50 - subCommandLine.Length;
if (padding < 1) padding = 1;
subCommandLine += new string(' ', padding) + "- " + subCommand.Description;
}
lines.Add(subCommandLine);
}
}
}
return BuildStringList(lines);
}
public static string GenerateSimpleUsage(string commandName, string usagePattern)
{
return "Usage: " + commandName + " " + usagePattern;
}
public static string GenerateMultiLineUsage(string commandName, List<CommandInfo> commandInfos)
{
List<string> lines = new List<string>();
lines.Add("Usage: " + commandName + " [subcommand] [args]");
lines.Add("");
foreach (var commandInfo in commandInfos)
{
string cmdDisplay = commandInfo.IsOptional ? "[" + commandInfo.Command + "]" : commandInfo.Command;
string commandLine = " " + commandName + " " + cmdDisplay;
if (!string.IsNullOrEmpty(commandInfo.Description))
{
int padding = 50 - commandLine.Length;
if (padding < 1) padding = 1;
commandLine += new string(' ', padding) + "- " + commandInfo.Description;
}
lines.Add(commandLine);
}
return BuildStringList(lines);
}
public static string GenerateDetailedUsage(string commandName, List<CommandInfo> commandInfos)
{
List<string> lines = new List<string>();
lines.Add("Usage: " + commandName + " [subcommand] [args]");
lines.Add("");
lines.Add("Available subcommands:");
lines.Add("");
foreach (var commandInfo in commandInfos)
{
string cmdDisplay = commandInfo.IsOptional ? "[" + commandInfo.Command + "]" : commandInfo.Command;
string commandLine = " " + cmdDisplay;
if (!string.IsNullOrEmpty(commandInfo.Description))
{
int padding = 30 - commandLine.Length;
if (padding < 1) padding = 1;
commandLine += new string(' ', padding) + "- " + commandInfo.Description;
}
lines.Add(commandLine);
if (commandInfo.SubCommands.Count > 0)
{
lines.Add("");
lines.Add(" " + commandInfo.Command + " options:");
lines.Add("");
foreach (var subCommand in commandInfo.SubCommands)
{
string subCmdDisplay = subCommand.IsOptional ? "[" + subCommand.Command + "]" : subCommand.Command;
string subCommandLine = " " + subCmdDisplay;
if (!string.IsNullOrEmpty(subCommand.Description))
{
int padding = 30 - subCommandLine.Length;
if (padding < 1) padding = 1;
subCommandLine += new string(' ', padding) + "- " + subCommand.Description;
}
lines.Add(subCommandLine);
}
lines.Add("");
}
}
return BuildStringList(lines);
}
public static string GenerateCompactUsage(string commandName, List<CommandInfo> commandInfos)
{
List<string> lines = new List<string>();
string commandPattern = BuildCommandPattern(commandInfos);
lines.Add("Usage: " + commandName + " <" + commandPattern + "> [args]");
lines.Add("");
int maxCommandLength = FindMaxCommandLength(commandInfos);
foreach (var commandInfo in commandInfos)
{
string cmdDisplay = commandInfo.IsOptional ? "[" + commandInfo.Command + "]" : commandInfo.Command;
string commandLine = " " + cmdDisplay;
if (!string.IsNullOrEmpty(commandInfo.Description))
{
int padding = maxCommandLength + 4 - commandLine.Length;
if (padding < 1) padding = 1;
commandLine += new string(' ', padding) + "- " + commandInfo.Description;
}
lines.Add(commandLine);
}
return BuildStringList(lines);
}
public static string GenerateVerticalUsage(string commandName, List<CommandInfo> commandInfos)
{
List<string> lines = new List<string>();
lines.Add("Usage: " + commandName + " [subcommand] [args]");
lines.Add("");
lines.Add("Available subcommands:");
lines.Add("");
foreach (var commandInfo in commandInfos)
{
string cmdDisplay = commandInfo.IsOptional ? "[" + commandInfo.Command + "]" : commandInfo.Command;
lines.Add(" " + cmdDisplay);
if (!string.IsNullOrEmpty(commandInfo.Description))
{
lines.Add(" " + commandInfo.Description);
}
if (commandInfo.SubCommands.Count > 0)
{
lines.Add(" Options:");
foreach (var subCommand in commandInfo.SubCommands)
{
string subCmdDisplay = subCommand.IsOptional ? "[" + subCommand.Command + "]" : subCommand.Command;
lines.Add(" " + subCmdDisplay);
if (!string.IsNullOrEmpty(subCommand.Description))
{
lines.Add(" " + subCommand.Description);
}
}
}
lines.Add("");
}
return BuildStringList(lines);
}
private static string BuildCommandPattern(List<CommandInfo> commandInfos)
{
string result = "";
for (int i = 0; i < commandInfos.Count; i++)
{
if (i > 0)
{
result += " | ";
}
string cmdDisplay = commandInfos[i].IsOptional ? "[" + commandInfos[i].Command + "]" : commandInfos[i].Command;
result += cmdDisplay;
}
return result;
}
private static int FindMaxCommandLength(List<CommandInfo> commandInfos)
{
int maxLen = 0;
foreach (var commandInfo in commandInfos)
{
int len = commandInfo.Command.Length;
if (len > maxLen)
{
maxLen = len;
}
}
return maxLen;
}
private static string BuildStringList(List<string> lines)
{
string result = "";
for (int i = 0; i < lines.Count; i++)
{
if (i > 0)
{
result += "\n";
}
result += lines[i];
}
return result;
}
}
}