// TARGET:powerpnt.exe /n // START_IN: ///////////// // PowerPoint Run // Workload: Activation-less Office Workloads // Version: 1.0.0 ///////////// using LoginPI.Engine.ScriptBase; using LoginPI.Engine.ScriptBase.Components; using System; using System.IO; using System.Runtime.InteropServices; using System.Threading; public class PowerPoint_Run_Office_Activation_less : ScriptBase { // ===================================================== // Imports & Constants // ===================================================== [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern void mouse_event(uint dwFlags, uint dx, uint dy, int dwData, UIntPtr dwExtraInfo); // ===================================================== // Configurable Variables // ===================================================== int globalTimeoutInSeconds = 60; // Maximum seconds to wait for windows/controls int globalWaitInSeconds = 3; // Standard pause between actions int waitMessageboxInSeconds = 2; // Duration to show on-screen wait messages int pageScrollCpm = 60; // CPM for PageUp/PageDown key repeats int pageScrollCount = 10; // Number of pages to scroll per scroll step int slideshowStartWait = 10; // Seconds to wait for slideshow to start int slideshowAdvanceCount = 5; // Number of slides to advance in slideshow int slideshowAdvanceCpm = 12; // CPM for DOWN-arrow slide advancement int saveDialogRetryCount = 2; // Attempts to locate the Save As dialog int typingCpm = 600; // CPM for typing file paths int startMenuWaitInSeconds = 5; // Seconds to wait around Start menu interactions int maxFileSizeChecks = 10; // Max poll loops before giving up on PDF size stabilization int fileSizeCheckInterval = 1000; // Milliseconds between each file‐size check // ===================================================== // Execute Method // ===================================================== private void Execute() { // Ensure TEMP\LoginEnterprise exists var temp = GetEnvironmentVariable("TEMP"); var lEDir = Path.Combine(temp, "LoginEnterprise"); if (!Directory.Exists(lEDir)) Directory.CreateDirectory(lEDir); // Simulate Start Menu interaction Log("Simulating Start Menu interaction."); Wait(startMenuWaitInSeconds); Type("{LWIN}", hideInLogging: false); Wait(startMenuWaitInSeconds); Type("{LWIN}", hideInLogging: false); Wait(1); Type("{ESC}", hideInLogging: false); Wait(startMenuWaitInSeconds); // Focus existing LoginVSI slide deck Log("Focusing existing LoginVSI PowerPoint deck."); var pptWin = FindWindow( className: "Win32 Window:PPTFrameClass", title: "*loginvsi*", processName: "POWERPNT", timeout: globalTimeoutInSeconds ); if (pptWin == null) ABORT("LoginVSI slide deck window not found."); pptWin.Focus(); pptWin.Maximize(); Wait(globalWaitInSeconds); // Scroll, minimize, maximize Wait(waitMessageboxInSeconds, showOnScreen: true, onScreenText: "Scrolling through presentation"); Log("Scrolling down."); pptWin.Type("{PAGEDOWN}".Repeat(pageScrollCount), cpm: pageScrollCpm, hideInLogging: false); Log("Scrolling up."); pptWin.Type("{PAGEUP}".Repeat(pageScrollCount), cpm: pageScrollCpm, hideInLogging: false); Wait(globalWaitInSeconds); pptWin.Minimize(); Wait(globalWaitInSeconds); pptWin.Maximize(); pptWin.Focus(); Wait(globalWaitInSeconds); // Run slideshow Wait(waitMessageboxInSeconds, showOnScreen: true, onScreenText: "Running slideshow"); Log("Starting slideshow"); pptWin.Type("{F5}", hideInLogging: false); Wait(slideshowStartWait); Log("Navigating slideshow slides"); pptWin.Type("{DOWN}".Repeat(slideshowAdvanceCount), cpm: slideshowAdvanceCpm, hideInLogging: false); Wait(globalWaitInSeconds); Log("Ending slideshow"); Type("{ESC}{ESC}", hideInLogging: false,cpm: slideshowAdvanceCpm); pptWin.Type("{ESC}{ESC}", hideInLogging: false,cpm: slideshowAdvanceCpm); Wait(globalWaitInSeconds); pptWin.Type("{HOME}", hideInLogging: false); Wait(globalWaitInSeconds); // PDF-print the slideshow Log("Printing slideshow to PDF"); pptWin.Type("{CTRL+P}", hideInLogging: false); // Find and click Print button var printBtn = pptWin.FindControl( className: "Button:NetUISimpleButton", title: "Print", timeout: globalTimeoutInSeconds, continueOnError: true ); if (printBtn == null) ABORT("Print button not found"); Wait(globalWaitInSeconds); pptWin.FindControl(className: "ComboBox:NetUIDropdownAnchor", title: "Which Printer", text: "Microsoft Print to PDF", timeout: globalTimeoutInSeconds); Wait(globalWaitInSeconds); printBtn.Click(); // Time Save As dialog appearance StartTimer("SaveAsDialog"); for (int i = 0; i < saveDialogRetryCount; i++) { var saveAs = FindWindow( className: "Win32 Window:#32770", title: "Save Print Output As", processName: "POWERPNT", timeout: globalTimeoutInSeconds, continueOnError: true ); if (saveAs == null) continue; StopTimer("SaveAsDialog"); Log("Save dialog opened."); var filenameBox = saveAs.FindControl( className: "Edit:Edit", title: "File name:", timeout: globalTimeoutInSeconds ); var pdfPath = Path.Combine(lEDir, "loginvsiPptPrint.pdf"); if (File.Exists(pdfPath)) RemoveFile(pdfPath); Wait(globalWaitInSeconds, showOnScreen: true, onScreenText: "Typing PDF file path"); ScriptHelpers.SetTextBoxText(this, filenameBox, pdfPath, cpm: typingCpm); saveAs.Type("{ENTER}", hideInLogging: false); Wait(globalWaitInSeconds); // Wait up to globalTimeoutInSeconds for the PDF to appear (size > 0) var start = DateTime.UtcNow; while ((DateTime.UtcNow - start).TotalSeconds < globalTimeoutInSeconds) { if (File.Exists(pdfPath) && new FileInfo(pdfPath).Length > 0) { Log("PDF file created, size is now > 0 bytes."); break; } Thread.Sleep(500); } // Poll until its size stops growing (or until maxFileSizeChecks) long lastSize = new FileInfo(pdfPath).Length; for (int loop = 0; loop < maxFileSizeChecks; loop++) { Thread.Sleep(fileSizeCheckInterval); if (File.Exists(pdfPath)) { var fi = new FileInfo(pdfPath); if (fi.Length == lastSize) { Log($"PDF size stabilized at {fi.Length} bytes after {loop + 1} checks."); break; } lastSize = fi.Length; } } break; } Log("PowerPoint Run complete; deck remains open."); } } // ===================================================== // Helper Class for TextBox Operations // ===================================================== public static class ScriptHelpers { public static void SetTextBoxText(ScriptBase script, IWindow textBox, string text, int cpm = 600) { int attempts = 0; string current = null; do { textBox.Type("{CTRL+a}", hideInLogging: false); script.Wait(1); textBox.Type(text, cpm: cpm, hideInLogging: false); script.Wait(1); current = textBox.GetText(); attempts++; } while (attempts < 5 && current != text); if (current != text) script.ABORT($"Unable to set text '{text}', got '{current}' after {attempts} attempts."); } }