public static void Run <TStartup>(string windowTitle, string hostHtmlPath, bool fullscreen = false, int x = 0, int y = 0, int width = 800, int height = 600) { DesktopSynchronizationContext.UnhandledException += (sender, exception) => { UnhandledException(exception); }; photinoWindow = new PhotinoWindow(windowTitle, options => { var contentRootAbsolute = Path.GetDirectoryName(Path.GetFullPath(hostHtmlPath)); options.CustomSchemeHandlers.Add(BlazorAppScheme, (string url, out string contentType) => { // TODO: Only intercept for the hostname 'app' and passthrough for others // TODO: Prevent directory traversal? var appFile = Path.Combine(contentRootAbsolute, new Uri(url).AbsolutePath.Substring(1)); if (appFile == contentRootAbsolute) { appFile = hostHtmlPath; } contentType = GetContentType(appFile); return(File.Exists(appFile) ? File.OpenRead(appFile) : null); }); // framework:// is resolved as embedded resources options.CustomSchemeHandlers.Add("framework", (string url, out string contentType) => { contentType = GetContentType(url); return(SupplyFrameworkFile(url)); }); }, width, height, x, y, fullscreen); CancellationTokenSource appLifetimeCts = new CancellationTokenSource(); Task.Factory.StartNew(async() => { try { var ipc = new IPC(photinoWindow); await RunAsync <TStartup>(ipc, appLifetimeCts.Token); } catch (Exception ex) { UnhandledException(ex); throw; } }); try { photinoWindow.Load(BlazorAppScheme + "://app/"); photinoWindow.WaitForClose(); } finally { appLifetimeCts.Cancel(); } }
static void Main(string[] args) { var mainWindow = new PhotinoWindow("Main Window") .RegisterWebMessageReceivedHandler(CloseWindowMessageDelegate) .RegisterWebMessageReceivedHandler(NewWindowMessageDelegate) .Resize(600, 400) .Center(); _mainWindow = mainWindow; mainWindow .Load("wwwroot/main.html") .WaitForClose(); }
internal static void Run(string workingDir, Uri baseUrl) { _mainWindow = CreateWindow(workingDir); _mainWindow.Load(baseUrl); _mainWindow.WaitForClose(); }
static void Main(string[] args) { FileDialogs.Init(); var serverStream = new SimplexStream(); var clientStream = new SimplexStream(); var encoding = new UTF8Encoding(false); var writer = new StreamWriter(serverStream, encoding); var formatter = new JsonMessageFormatter(encoding); Serializer.PrepareSerializer(formatter.JsonSerializer); var messageHandler = new NewLineDelimitedMessageHandler(clientStream, serverStream, formatter); var server = new FullServer(messageHandler); server.Workspace.SettingsService.RegisterSetting(DisplaySettingsNames.Theme, typeof(string), "xp/98.css"); server.Agent.IsReady += (o, e) => { if (args.Length == 1) { var _ = server.Workspace.ExecuteCommand("File.Open", args[0]); } }; // try to load settings string[] settingsLines = Array.Empty <string>(); var settingsFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".bcadconfig"); try { settingsLines = File.ReadAllLines(settingsFilePath); server.Workspace.SettingsService.LoadFromLines(settingsLines); server.Workspace.Update(isDirty: false); } catch { // don't really care if it failed } #if DEBUG var allowDebugging = true; var logVerbosity = 1; var clientArguments = new[] { "--", "debug" }; #else var allowDebugging = false; var logVerbosity = 0; var clientArguments = new[] { "--" }; #endif var window = new PhotinoWindow() .SetUseOsDefaultSize(true) .SetContextMenuEnabled(false) .Center() .SetDevToolsEnabled(allowDebugging) .SetResizable(true) .SetLogVerbosity(logVerbosity) .RegisterWebMessageReceivedHandler((object sender, string message) => { try { // forward JSON from client to server writer.WriteLine(message); writer.Flush(); } catch { // don't let this die } }); SetTitle(window, server.Workspace); window.RegisterCustomSchemeHandler("app", (object sender, string scheme, string url, out string contentType) => { contentType = "text/javascript"; var script = $"var clientArguments = [{string.Join(", ", clientArguments.Select(arg => $"\"{arg}\""))}];"; return(new MemoryStream(Encoding.UTF8.GetBytes(script))); }); var fileSystemService = new FileSystemService(action => { window.Invoke(action); }); server.Workspace.RegisterService(fileSystemService); server.Workspace.WorkspaceChanged += (sender, args) => SetTitle(window, server.Workspace); var doHardClose = false; window.WindowClosing += (sender, args) => { if (doHardClose) { // close immediately return(false); } if (server.Workspace.IsDirty) { var _ = Task.Run(async() => { var result = await server.Workspace.PromptForUnsavedChanges(); if (result != UnsavedChangesResult.Cancel) { doHardClose = true; window.Close(); } }); // don't close yet return(true); } return(false); }; var _ = Task.Run(async() => { var reader = new StreamReader(clientStream, encoding); while (true) { try { var line = await reader.ReadLineAsync(); window.SendWebMessage(line); } catch { // don't let this die } } }); server.Start(); var indexPath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "index.html"); window.Load(indexPath); window.WaitForClose(); // try to save settings try { var newSettingsContents = server.Workspace.SettingsService.WriteWithLines(settingsLines); File.WriteAllText(settingsFilePath, newSettingsContents); } catch { // don't really care if it failed } }