重写OOBE

This commit is contained in:
2026-04-04 17:52:41 +08:00
parent c189be5d88
commit 1341f10ed9
4 changed files with 222 additions and 188 deletions

View File

@@ -1 +1 @@
2026-04-04 15:17:52 2026-04-04 17:44:58

View File

@@ -1 +1 @@
78601d5 c189be5

View File

@@ -49,7 +49,7 @@ namespace CMLeonOS.Gui.ShellComponents.Dock
internal static readonly int IconSize = 64; internal static readonly int IconSize = 64;
internal static readonly int IconImageMaxSize = 48; internal static readonly int IconImageMaxSize = 48;
private static readonly Color DockBackground = Color.FromArgb(211, 211, 211); private static readonly Color DockBackground = Color.FromArgb(160, 128, 128, 128);
private static readonly Color ActiveIconBackground = Color.FromArgb(160, 190, 255); private static readonly Color ActiveIconBackground = Color.FromArgb(160, 190, 255);
private static readonly Color ActiveIndicator = Color.FromArgb(36, 88, 196); private static readonly Color ActiveIndicator = Color.FromArgb(36, 88, 196);

View File

@@ -425,197 +425,231 @@ namespace CMLeonOS
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black); CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.Clear(); global::System.Console.Clear();
var termsBox = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(5, 5, 70, 18), "User Terms and Conditions", () => { }, true); RenderOobeScreen("Welcome to CMLeonOS Setup", new string[]
termsBox.Render(); {
"This wizard will configure your first administrator account.",
"Steps: Terms -> Admin User -> Hostname -> Finish.",
"",
"Press Enter to continue."
}, global::System.ConsoleColor.Cyan);
global::System.Console.ReadLine();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Gray, global::System.ConsoleColor.Black); RenderOobeScreen("User Terms", new string[]
global::System.Console.SetCursorPosition(7, 7); {
global::System.Console.WriteLine("1. This operating system is provided as-is without warranty"); "1. This operating system is provided as-is without warranty.",
global::System.Console.SetCursorPosition(7, 8); "2. You are responsible for your data and backups.",
global::System.Console.WriteLine("2. You are responsible for your data and backups"); "3. Unauthorized access attempts may be logged.",
global::System.Console.SetCursorPosition(7, 9); "4. Administrators have full access to local data.",
global::System.Console.WriteLine("3. Unauthorized access attempts may be logged"); "5. By using this system, you agree to these terms.",
global::System.Console.SetCursorPosition(7, 10); "6. Data is stored locally on this machine.",
global::System.Console.WriteLine("4. System administrators have full access to all data"); "7. Support: https://lbbs.ecuil.com/#/thread/category/10"
global::System.Console.SetCursorPosition(7, 11); }, global::System.ConsoleColor.Cyan);
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: https://lbbs.ecuil.com/#/thread/category/10");
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; if (!PromptYesNo(6, 19, "Accept terms? (yes/no): "))
while (!termsAccepted) {
WriteStatus(6, 21, "Terms were not accepted. Rebooting...", global::System.ConsoleColor.Red);
global::System.Threading.Thread.Sleep(2000);
Sys.Power.Reboot();
return;
}
string username = string.Empty;
while (true)
{
RenderOobeScreen("Create Administrator", new string[]
{ {
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black); "Create your first admin account.",
global::System.Console.SetCursorPosition(5, 24); "Username cannot contain: < > : \" | ? * / \\ or space."
global::System.Console.Write("Do you accept the User Terms? (yes/no): "); }, global::System.ConsoleColor.Cyan);
string response = global::System.Console.ReadLine()?.ToLower();
if (response == "yes" || response == "y") username = PromptText(6, 10, "Username: ");
{ if (string.IsNullOrWhiteSpace(username))
termsAccepted = true; {
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black); WriteStatus(6, 21, "Username cannot be empty.", global::System.ConsoleColor.Red);
global::System.Console.SetCursorPosition(5, 24); global::System.Threading.Thread.Sleep(1200);
global::System.Console.Write("Terms accepted. "); continue;
} }
else if (response == "no" || response == "n") if (ContainsInvalidChars(username))
{ {
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black); WriteStatus(6, 21, "Username contains invalid characters.", global::System.ConsoleColor.Red);
global::System.Console.SetCursorPosition(5, 24); global::System.Threading.Thread.Sleep(1200);
global::System.Console.Write("You must accept the User Terms to continue."); continue;
global::System.Threading.Thread.Sleep(2000); }
Sys.Power.Reboot(); break;
} }
else
{ string password = string.Empty;
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black); while (true)
global::System.Console.SetCursorPosition(5, 24); {
global::System.Console.Write("Invalid response. Please enter 'yes' or 'no'."); RenderOobeScreen("Create Administrator", new string[]
} {
"Create your first admin account.",
"Username: " + username
}, global::System.ConsoleColor.Cyan);
password = PromptPassword(6, 11, "Password: ");
string confirmPassword = PromptPassword(6, 12, "Confirm Password: ");
if (string.IsNullOrWhiteSpace(password))
{
WriteStatus(6, 21, "Password cannot be empty.", global::System.ConsoleColor.Red);
global::System.Threading.Thread.Sleep(1200);
continue;
}
if (password != confirmPassword)
{
WriteStatus(6, 21, "Passwords do not match.", global::System.ConsoleColor.Red);
global::System.Threading.Thread.Sleep(1200);
continue;
}
break;
}
string hostname = string.Empty;
while (true)
{
RenderOobeScreen("Device Name", new string[]
{
"Choose a hostname for this device.",
"Example: CMLEON-PC"
}, global::System.ConsoleColor.Cyan);
hostname = PromptText(6, 10, "Hostname: ");
if (string.IsNullOrWhiteSpace(hostname))
{
WriteStatus(6, 21, "Hostname cannot be empty.", global::System.ConsoleColor.Red);
global::System.Threading.Thread.Sleep(1200);
continue;
}
break;
}
try
{
User adminUser = new User
{
Username = username,
Password = password,
IsAdmin = true,
Hostname = hostname
};
users.Add(adminUser);
SaveUsers();
RenderOobeScreen("Setup Complete", new string[]
{
"Administrator account created successfully.",
"User: " + username,
"Hostname: " + hostname,
"",
"System will reboot in 3 seconds..."
}, global::System.ConsoleColor.Green);
global::System.Threading.Thread.Sleep(3000);
Sys.Power.Reboot();
}
catch (Exception ex)
{
RenderOobeScreen("Setup Error", new string[]
{
"Failed to finish setup:",
ex.Message,
"",
"Press Enter to reboot."
}, global::System.ConsoleColor.Red);
global::System.Console.ReadLine();
Sys.Power.Reboot();
}
}
private void RenderOobeScreen(string title, string[] lines, global::System.ConsoleColor accent)
{
global::System.Console.Clear();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Cyan, global::System.ConsoleColor.Black);
int left = 4;
int top = 2;
int width = 72;
int height = 22;
string horizontal = new string('-', width - 2);
global::System.Console.SetCursorPosition(left, top);
global::System.Console.Write("+" + horizontal + "+");
for (int y = 1; y < height - 1; y++)
{
global::System.Console.SetCursorPosition(left, top + y);
global::System.Console.Write("|" + new string(' ', width - 2) + "|");
}
global::System.Console.SetCursorPosition(left, top + height - 1);
global::System.Console.Write("+" + horizontal + "+");
CMLeonOS.UI.TUIHelper.SetColors(accent, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(left + 2, top + 1);
global::System.Console.Write(title);
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Gray, global::System.ConsoleColor.Black);
int lineY = top + 3;
for (int i = 0; i < lines.Length; i++)
{
global::System.Console.SetCursorPosition(left + 2, lineY + i);
string line = lines[i] ?? string.Empty;
if (line.Length > width - 4)
{
line = line.Substring(0, width - 4);
}
global::System.Console.Write(line.PadRight(width - 4));
}
}
private string PromptText(int x, int y, string label)
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(x, y);
global::System.Console.Write(new string(' ', 68));
global::System.Console.SetCursorPosition(x, y);
global::System.Console.Write(label);
return global::System.Console.ReadLine();
}
private string PromptPassword(int x, int y, string label)
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(x, y);
global::System.Console.Write(new string(' ', 68));
global::System.Console.SetCursorPosition(x, y);
global::System.Console.Write(label);
return ReadPassword();
}
private void WriteStatus(int x, int y, string text, global::System.ConsoleColor color)
{
CMLeonOS.UI.TUIHelper.SetColors(color, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(x, y);
if (text.Length > 68)
{
text = text.Substring(0, 68);
}
global::System.Console.Write(text.PadRight(68));
}
private bool PromptYesNo(int x, int y, string label)
{
while (true)
{
string input = PromptText(x, y, label);
string answer = (input ?? string.Empty).Trim().ToLower();
if (answer == "yes" || answer == "y")
{
return true;
}
if (answer == "no" || answer == "n")
{
return false;
} }
global::System.Console.Clear(); WriteStatus(x, y + 2, "Please type yes or no.", global::System.ConsoleColor.Red);
}
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))
{
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();
}
while (ContainsInvalidChars(username))
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Username contains invalid characters: < > : \" | ? * / \\ space");
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: ");
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)
{
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();
}
try
{
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();
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();
}
catch (Exception ex)
{
ShowError($"Error creating admin user: {ex.Message}");
}
} }
private void CreateUserFolder(string username) private void CreateUserFolder(string username)