//! Wizard UI for installation process use anyhow::Result; use native_windows_gui as nwg; use native_windows_derive as nwd; use crate::{install_wintun_dll, service, firewall}; #[derive(Default, nwd::NwgUi)] pub struct InstallerWizard { #[nwg_control(size: (600, 400), position: (300, 300), title: "OSTP Installer", flags: "WINDOW|VISIBLE")] #[nwg_events(OnWindowClose: [InstallerWizard::exit])] window: nwg::Window, #[nwg_layout(parent: window, spacing: 1)] grid: nwg::GridLayout, #[nwg_control(text: "Welcome to OSTP Installer", font: Some(&data.title_font))] #[nwg_layout_item(layout: grid, row: 0, col: 0, col_span: 2)] title: nwg::Label, #[nwg_control(text: "This wizard will install OSTP VPN on your system.\n\nClick Next to continue.")] #[nwg_layout_item(layout: grid, row: 1, col: 0, col_span: 2, row_span: 4)] description: nwg::Label, #[nwg_control(text: "Next")] #[nwg_layout_item(layout: grid, row: 5, col: 1)] #[nwg_events(OnButtonClick: [InstallerWizard::next])] next_button: nwg::Button, #[nwg_control(text: "Cancel")] #[nwg_layout_item(layout: grid, row: 5, col: 0)] #[nwg_events(OnButtonClick: [InstallerWizard::exit])] cancel_button: nwg::Button, #[nwg_resource(family: "Segoe UI", size: 18, weight: 700)] title_font: nwg::Font, step: std::cell::RefCell, } impl InstallerWizard { fn next(&self) { let mut step = self.step.borrow_mut(); *step += 1; match *step { 1 => self.install_step(), 2 => self.finish_step(), _ => {} } } fn install_step(&self) { self.title.set_text("Installing..."); self.description.set_text("Please wait while OSTP is being installed."); self.next_button.set_enabled(false); // Perform installation std::thread::spawn(move || { if let Err(e) = perform_installation() { eprintln!("Installation error: {}", e); } }); } fn finish_step(&self) { self.title.set_text("Installation Complete"); self.description.set_text("OSTP has been successfully installed.\n\nClick Finish to exit."); self.next_button.set_text("Finish"); } fn exit(&self) { nwg::stop_thread_dispatch(); } } pub fn run_wizard() -> Result<()> { nwg::init()?; nwg::Font::set_global_family("Segoe UI")?; let _app = InstallerWizard::default(); nwg::dispatch_thread_events(); Ok(()) } fn perform_installation() -> Result<()> { tracing::info!("Step 1: Installing Wintun DLL"); install_wintun_dll()?; tracing::info!("Step 2: Registering Windows Service"); service::install_service()?; tracing::info!("Step 3: Configuring Firewall"); firewall::add_firewall_rules()?; tracing::info!("Installation complete"); Ok(()) }