using System; using System.Diagnostics; using System.IO; using System.Net.Http; using System.Threading.Tasks; namespace InstaSoftOfficeTool.Services { public class MsiInstaller { public event Action StatusChanged; public event Action DownloadProgress; private string _isoPath; private string _mountedDrive; public string WorkFolder { get; private set; } public MsiInstaller() { WorkFolder = Path.Combine(Path.GetTempPath(), "InstaSoftODT"); Directory.CreateDirectory(WorkFolder); } public async Task DownloadIsoAsync(string url) { try { string fileName = Path.GetFileName(new Uri(url).AbsolutePath); _isoPath = Path.Combine(WorkFolder, fileName); // Check if already downloaded if (File.Exists(_isoPath)) { var fi = new FileInfo(_isoPath); if (fi.Length > 100_000_000) { StatusChanged?.Invoke("ISO már letöltve: " + fileName + " (" + (fi.Length / 1024 / 1024) + " MB)"); return true; } File.Delete(_isoPath); } StatusChanged?.Invoke("ISO letöltése: " + fileName); StatusChanged?.Invoke("URL: " + url); using (var handler = new HttpClientHandler { AllowAutoRedirect = true }) using (var client = new HttpClient(handler)) { client.DefaultRequestHeaders.Add("User-Agent", "InstaSoftOfficeTool/1.0"); client.Timeout = TimeSpan.FromMinutes(30); var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); long totalBytes = response.Content.Headers.ContentLength ?? -1; using (var stream = await response.Content.ReadAsStreamAsync()) using (var fileStream = new FileStream(_isoPath, FileMode.Create, FileAccess.Write, FileShare.None, 65536)) { var buffer = new byte[65536]; long totalRead = 0; int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { await fileStream.WriteAsync(buffer, 0, bytesRead); totalRead += bytesRead; DownloadProgress?.Invoke(totalRead, totalBytes); } } var downloadedSize = new FileInfo(_isoPath).Length; StatusChanged?.Invoke("ISO letöltve: " + (downloadedSize / 1024 / 1024) + " MB"); } return true; } catch (HttpRequestException ex) { StatusChanged?.Invoke("Hálózati hiba: " + ex.Message); return false; } catch (TaskCanceledException) { StatusChanged?.Invoke("Időtúllépés: A letöltés túl sokáig tartott."); return false; } catch (Exception ex) { StatusChanged?.Invoke("ISO letöltési hiba: " + ex.Message); return false; } } public async Task MountIsoAsync() { try { StatusChanged?.Invoke("ISO csatolása..."); var psi = new ProcessStartInfo { FileName = "powershell", Arguments = "-NoProfile -Command \"" + "$result = Mount-DiskImage -ImagePath '" + _isoPath + "' -PassThru; " + "$vol = $result | Get-Volume; " + "Write-Output $vol.DriveLetter\"", UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }; using (var process = Process.Start(psi)) { string output = await Task.Run(() => process.StandardOutput.ReadToEnd()); await Task.Run(() => process.WaitForExit()); string driveLetter = output.Trim(); if (process.ExitCode != 0 || driveLetter.Length != 1 || !char.IsLetter(driveLetter[0])) { string error = await Task.Run(() => process.StandardError.ReadToEnd()); StatusChanged?.Invoke("Hiba: Az ISO csatolása sikertelen."); if (!string.IsNullOrEmpty(error)) StatusChanged?.Invoke(error.Trim()); return false; } _mountedDrive = driveLetter + ":\\"; StatusChanged?.Invoke("ISO csatolva: " + _mountedDrive); return true; } } catch (Exception ex) { StatusChanged?.Invoke("ISO csatolási hiba: " + ex.Message); return false; } } public async Task RunSetupAsync(Action outputCallback) { string setupExe = Path.Combine(_mountedDrive, "setup.exe"); if (!File.Exists(setupExe)) { StatusChanged?.Invoke("Hiba: setup.exe nem található: " + setupExe); return -1; } StatusChanged?.Invoke("Office 2016 telepítő indítása: " + setupExe); outputCallback?.Invoke("A Microsoft Office telepítő ablaka megjelenik..."); outputCallback?.Invoke("Kérjük, kövesse a telepítő utasításait."); var psi = new ProcessStartInfo { FileName = setupExe, UseShellExecute = true }; using (var process = Process.Start(psi)) { await Task.Run(() => process.WaitForExit()); return process.ExitCode; } } public async Task DismountIsoAsync() { try { if (string.IsNullOrEmpty(_isoPath) || !File.Exists(_isoPath)) return; StatusChanged?.Invoke("ISO leválasztása..."); var psi = new ProcessStartInfo { FileName = "powershell", Arguments = "-NoProfile -Command \"Dismount-DiskImage -ImagePath '" + _isoPath + "'\"", UseShellExecute = false, CreateNoWindow = true }; using (var process = Process.Start(psi)) { await Task.Run(() => process.WaitForExit()); } StatusChanged?.Invoke("ISO leválasztva."); } catch { } } } }