Co-locate the two cockpit-pod projects into a single repository:
- Console/ : TeslaConsole, the net48 WinForms operator console (decompiled
reconstruction) plus its differential + catalog test suite.
- Launcher/ : TeslaLauncher, the net6 pod-side Service + Agent rewrite.
Adds a combined TeslaSuite.sln, root README documenting the shared wire
contract (and its current duplication, the main follow-up), and a root
.gitignore. Histories were not preserved per request; this is a fresh start
from the current working state of both projects.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
139 lines
4.5 KiB
C#
139 lines
4.5 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.IO.IsolatedStorage;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
|
|
namespace TeslaConsole;
|
|
|
|
internal static class Program
|
|
{
|
|
private static Mutex sInstanceMutex = null;
|
|
|
|
private static readonly string sExceptionFile = Path.Combine(GetCommonAppDataDirectory(), "ExceptionLog.txt");
|
|
|
|
[STAThread]
|
|
private static void Main(string[] args)
|
|
{
|
|
if (args.Length >= 1 && args[0] == "/migrateIsoStore")
|
|
{
|
|
try
|
|
{
|
|
string path = Path.Combine(GetCommonAppDataDirectory(), "local.siteconfig");
|
|
IsolatedStorageFile machineStoreForAssembly = IsolatedStorageFile.GetMachineStoreForAssembly();
|
|
if (machineStoreForAssembly.GetFileNames("local.siteconfig").Length > 0)
|
|
{
|
|
using (IsolatedStorageFileStream isolatedStorageFileStream = new IsolatedStorageFileStream("local.siteconfig", FileMode.Open, FileAccess.Read, FileShare.Read, machineStoreForAssembly))
|
|
{
|
|
using FileStream fileStream = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.Read);
|
|
byte[] array = new byte[4096];
|
|
int count;
|
|
while ((count = isolatedStorageFileStream.Read(array, 0, array.Length)) > 0)
|
|
{
|
|
fileStream.Write(array, 0, count);
|
|
}
|
|
isolatedStorageFileStream.Close();
|
|
fileStream.Close();
|
|
}
|
|
machineStoreForAssembly.DeleteFile("local.siteconfig");
|
|
}
|
|
Environment.Exit(0);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.ToString());
|
|
Environment.Exit(1);
|
|
}
|
|
}
|
|
sInstanceMutex = new Mutex(initiallyOwned: false, "TeslaConsole1Instance", out var createdNew);
|
|
if (!createdNew)
|
|
{
|
|
MessageBox.Show("Another instance of the Tesla Console is alread open.", "Tesla Console Open", MessageBoxButtons.OK);
|
|
return;
|
|
}
|
|
if (!Debugger.IsAttached)
|
|
{
|
|
Application.ThreadException += Application_ThreadException;
|
|
}
|
|
Application.EnableVisualStyles();
|
|
Application.SetCompatibleTextRenderingDefault(defaultValue: false);
|
|
Application.Run(new TeslaConsoleForm());
|
|
}
|
|
|
|
internal static string GetCommonAppDataDirectory()
|
|
{
|
|
string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Tesla Console");
|
|
if (!Directory.Exists(text))
|
|
{
|
|
Directory.CreateDirectory(text);
|
|
}
|
|
return text;
|
|
}
|
|
|
|
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
|
{
|
|
LogExceptionAndShowDialog(e.Exception, "An unhandled exception occurred, and the console must exit.", "Unhandled Exception");
|
|
Environment.Exit(1);
|
|
}
|
|
|
|
public static bool LogException(Exception ex, string generalMessage)
|
|
{
|
|
return LogString((generalMessage != null) ? generalMessage : "No general message available.", (ex != null) ? ex.ToString() : "The exception was null!");
|
|
}
|
|
|
|
public static bool LogMessage(string generalMessage)
|
|
{
|
|
return LogString(generalMessage, null);
|
|
}
|
|
|
|
private static bool LogString(string generalString, string exceptionString)
|
|
{
|
|
try
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
stringBuilder.AppendLine("**********");
|
|
stringBuilder.AppendLine(DateTime.Now.ToString());
|
|
if (!string.IsNullOrEmpty(generalString))
|
|
{
|
|
stringBuilder.AppendLine(generalString);
|
|
}
|
|
if (!string.IsNullOrEmpty(exceptionString))
|
|
{
|
|
stringBuilder.AppendLine(exceptionString);
|
|
}
|
|
lock (sExceptionFile)
|
|
{
|
|
string commonAppDataDirectory = GetCommonAppDataDirectory();
|
|
if (!Directory.Exists(commonAppDataDirectory))
|
|
{
|
|
Directory.CreateDirectory(commonAppDataDirectory);
|
|
}
|
|
File.AppendAllText(sExceptionFile, stringBuilder.ToString(), Encoding.UTF8);
|
|
}
|
|
return true;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static void LogExceptionAndShowDialog(Exception ex, string generalMessage, string messageBoxTitle)
|
|
{
|
|
if (LogException(ex, generalMessage))
|
|
{
|
|
MessageBox.Show($"{generalMessage} The associated exception has been logged in \"{sExceptionFile}\". Please send this file to support@elsewhenstudios.com", messageBoxTitle, MessageBoxButtons.OK);
|
|
return;
|
|
}
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
stringBuilder.AppendLine((generalMessage != null) ? generalMessage : "No general message available.");
|
|
stringBuilder.AppendLine();
|
|
stringBuilder.AppendLine("The associated exception could not be logged. Please give the following information to support@elsewhenstudios.com");
|
|
stringBuilder.AppendLine();
|
|
stringBuilder.AppendLine((ex != null) ? ex.ToString() : "The exception was null!");
|
|
MessageBox.Show(stringBuilder.ToString(), messageBoxTitle, MessageBoxButtons.OK);
|
|
}
|
|
}
|