using System; using System.IO; using System.Net.Http; using System.Threading.Tasks; namespace InstaSoftOfficeTool.Services { public class OdtDownloader { // Direct CDN link to ODT setup.exe (no self-extractor needed) private const string OdtDownloadUrl = "https://officecdn.microsoft.com/pr/wsus/setup.exe"; public event Action StatusChanged; public string OdtFolder { get; private set; } public string SetupExePath { get; private set; } public OdtDownloader() { OdtFolder = Path.Combine(Path.GetTempPath(), "InstaSoftODT"); } public async Task DownloadAndExtractAsync() { try { SetupExePath = Path.Combine(OdtFolder, "setup.exe"); // Check if valid setup.exe already exists if (File.Exists(SetupExePath)) { var existingSize = new FileInfo(SetupExePath).Length; if (existingSize > 1000000) // valid setup.exe is ~7MB { StatusChanged?.Invoke("Az ODT setup.exe m\u00e1r el\u00e9rhet\u0151 (" + (existingSize / 1024 / 1024) + " MB)."); return true; } // Delete corrupted file StatusChanged?.Invoke("S\u00e9r\u00fclt setup.exe t\u00f6rl\u00e9se..."); File.Delete(SetupExePath); } Directory.CreateDirectory(OdtFolder); // Download setup.exe directly from CDN StatusChanged?.Invoke("Office Deployment Tool let\u00f6lt\u00e9se..."); StatusChanged?.Invoke("URL: " + OdtDownloadUrl); 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(5); var response = await client.GetAsync(OdtDownloadUrl); if (!response.IsSuccessStatusCode) { StatusChanged?.Invoke("Hiba: HTTP " + (int)response.StatusCode + " " + response.StatusCode); return false; } var contentType = response.Content.Headers.ContentType?.MediaType ?? ""; if (contentType.Contains("text/html")) { StatusChanged?.Invoke("Hiba: HTML oldal \u00e9rkezett exe helyett."); StatusChanged?.Invoke("T\u00f6ltse le manu\u00e1lisan: https://www.microsoft.com/en-us/download/details.aspx?id=49117"); return false; } var bytes = await response.Content.ReadAsByteArrayAsync(); File.WriteAllBytes(SetupExePath, bytes); StatusChanged?.Invoke("Let\u00f6ltve: " + (bytes.Length / 1024) + " KB"); } if (!File.Exists(SetupExePath) || new FileInfo(SetupExePath).Length < 1000000) { StatusChanged?.Invoke("Hiba: A let\u00f6lt\u00f6tt f\u00e1jl s\u00e9r\u00fclt vagy t\u00fal kicsi."); return false; } StatusChanged?.Invoke("ODT setup.exe k\u00e9sz."); return true; } catch (System.Net.Http.HttpRequestException ex) { StatusChanged?.Invoke("H\u00e1l\u00f3zati hiba: Nincs internetkapcsolat vagy a szerver nem el\u00e9rhet\u0151."); StatusChanged?.Invoke("R\u00e9szletek: " + ex.Message); return false; } catch (TaskCanceledException) { StatusChanged?.Invoke("Id\u0151t\u00fall\u00e9p\u00e9s: A let\u00f6lt\u00e9s t\u00fal sok\u00e1ig tartott. Ellen\u0151rizze az internetkapcsolatot."); return false; } catch (Exception ex) { StatusChanged?.Invoke("Hiba: " + ex.GetType().Name + ": " + ex.Message); return false; } } public async Task RunSetupAsync(string configXmlPath, Action outputCallback) { var runner = new ProcessRunner(); runner.OutputReceived += line => outputCallback?.Invoke(line); StatusChanged?.Invoke("Office telep\u00edt\u00e9s ind\u00edt\u00e1sa..."); return await runner.RunAsync(SetupExePath, "/configure \"" + configXmlPath + "\""); } public async Task RunRemoveAsync(string configXmlPath, Action outputCallback) { var runner = new ProcessRunner(); runner.OutputReceived += line => outputCallback?.Invoke(line); StatusChanged?.Invoke("Office elt\u00e1vol\u00edt\u00e1s ind\u00edt\u00e1sa..."); return await runner.RunAsync(SetupExePath, "/configure \"" + configXmlPath + "\""); } } }