This project is read-only.

Test-Powerpoint

Topics: Archive - General
Jan 21, 2014 at 8:09 AM
Hi!

I want to prevent installation dialogs appearing when the user uses Powerpoint in presentation mode.

How to use the Test-Powerpoint command? I can't get it working. My code as follows:

*===============================================

* PRE-INSTALLATION

if (test-powerpoint -eq $true) {Exit-Script -ExitCode "5000"}
If ($deploymentType -ne "uninstall") { $installPhase = "Pre-Installation"

*===============================================

.
.
.

Even if I have the Powerpoint in presentation mode, I get all the installation dialogs, the script won't exit.

Could someone guide me to the right direction?

Thanks in advance!
Jan 21, 2014 at 1:53 PM
Hi there,

It seems the Test-PowerPoint function isn't working as expected. I've figured out why but I'm still trying to figure out how best to fix :\

The workaround right now would be to check if PowerPoint is running and exit if it is. Unfortunately this isn't exactly what you're looking for as it can't check if a presentation is running or not but it's the best I can suggest at the moment.
If (Get-Process "powerpnt" -ErrorAction SilentlyContinue) { Exit-Script -ExitCode 5000 }
Hope this helps. Dan
Jan 22, 2014 at 6:57 AM
Hi Dan,

ok. Hopefully you'll find a way to fix this :)

Suggested workaround is enough right now, thanks for the tip. I'll try that.

Btw, this toolkit is really awesome!

Best regards, Lasse
Apr 2, 2014 at 2:37 PM
Did you fix the problem with test-powerpoint?
Apr 28, 2014 at 9:01 AM
Greetings! I've been working on a very same problem and created the following code to return $true if PPT is in the slideshow mode (aka full-screen presentation mode):
if (!(Get-Process powerpnt -ErrorAction SilentlyContinue)) {$false}

Else {

$ppt = [Runtime.InteropServices.Marshal]::GetActiveObject('Powerpoint.Application')

if (($ppt.SlideShowWindows | select -ExpandProperty IsFullScreen) -eq "-1") {$true}
Else {$false}

}
Apr 29, 2014 at 2:39 PM
Afraid this won't work - PowerPoint is running in the current user session, but the App Deploy Toolkit runs with different privileges (either as current user with Admin rights, or as SYSTEM) - GetActiveObject will always return "Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))"

:(
Apr 29, 2014 at 3:15 PM
Indeed - not as function :(
however a global condition elevated under user's account should work
Apr 29, 2014 at 3:20 PM
Unfortunately I don't believe this will work either - elevation levels need to be the same. It's a security feature as far as I know. Some details here: http://social.msdn.microsoft.com/Forums/en-US/fb3dee79-9cbc-46a3-8c61-b9b83aca4e37/getactiveobject-failing-when-run-as-administrator-on-windows-7?forum=csharplanguage
Sep 26, 2014 at 7:49 AM
Edited Sep 26, 2014 at 11:26 AM
I know this is an old thread, but I've figured out a way to discover when PowerPoint is actually in fullscreen presentation mode.
$FullScreenWindowSource = @'
        using System;
        using System.Text;
        using System.Runtime.InteropServices;

        namespace ScreenDetection
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct RECT
            {
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;
            }
            
            public class FullScreen
            {
                [DllImport("user32.dll")]
                private static extern IntPtr GetForegroundWindow();
                
                [DllImport("user32.dll")]
                private static extern IntPtr GetDesktopWindow();
                
                [DllImport("user32.dll")]
                private static extern IntPtr GetShellWindow();
                
                [DllImport("user32.dll", SetLastError = true)]
                private static extern int GetWindowRect(IntPtr hWnd, out RECT rc);

                [DllImport("user32.dll")]
                static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
                
                private static IntPtr desktopHandle;
                private static IntPtr shellHandle;
                
                public static bool IsFullScreenWindow(string fullScreenWindowTitle)
                {
                    desktopHandle = GetDesktopWindow();
                    shellHandle   = GetShellWindow();
                    
                    bool runningFullScreen = false;
                    RECT appBounds;
                    System.Drawing.Rectangle screenBounds;
                    const int nChars = 256;
                    StringBuilder Buff = new StringBuilder(nChars);
                    string mainWindowTitle = "";
                    IntPtr hWnd;
                    hWnd = GetForegroundWindow();
                    
                    if (hWnd != null && !hWnd.Equals(IntPtr.Zero))
                    {
                        if (!(hWnd.Equals(desktopHandle) || hWnd.Equals(shellHandle)))
                        {
                            if (GetWindowText(hWnd, Buff, nChars) > 0)
                            {
                                mainWindowTitle = Buff.ToString();
                                //Console.WriteLine(mainWindowTitle)
                            }
                            
                            // If the main window title contains the text being searched for, then check to see if the window is in fullscreen mode.
                            if ((!string.IsNullOrEmpty(fullScreenWindowTitle)) && mainWindowTitle.Contains(fullScreenWindowTitle))
                            {
                                GetWindowRect(hWnd, out appBounds);
                                screenBounds = System.Windows.Forms.Screen.FromHandle(hWnd).Bounds;
                                if ((appBounds.Bottom - appBounds.Top) == screenBounds.Height && (appBounds.Right - appBounds.Left) == screenBounds.Width)
                                {
                                    runningFullScreen = true;
                                }
                            }
                        }
                    }
                    
                    return runningFullScreen;
                }
            }
        }
'@
        
        If (-not ([System.Management.Automation.PSTypeName]'ScreenDetection.FullScreen').Type)
        {
            $ReferencedAssemblies = ('System.Drawing','System.Windows.Forms')
            Add-Type -TypeDefinition $FullScreenWindowSource -ReferencedAssemblies $ReferencedAssemblies -Language CSharp
        }
        
        [boolean]$PowerPointFullScreenMode = $false
        If (Get-Process -Name 'POWERPNT' -ErrorAction 'SilentlyContinue')
        {
            [boolean]$PowerPointFullScreenMode = [ScreenDetection.FullScreen]::IsFullScreenWindow('PowerPoint Slide Show')
        }

        Write-Output $PowerPointFullScreenMode
Sep 26, 2014 at 7:53 AM
Sintaxasn, it is never too late for great ideas :) Does your code work when executed within the system context?
Sep 26, 2014 at 8:22 AM
Yes, this should work in the system context.
Nov 4, 2014 at 1:14 AM
This code has been integrated into the toolkit with the latest 3.5.0 release.
Nov 4, 2014 at 2:11 PM
Great news indeed!! Thank you.

What we have noticed with this code is that it does not work in a multi-monitor scenario, e.g. when a presnetation is running full-screen on a secondary monitor.
Nov 4, 2014 at 2:38 PM
The way the code works, it tries to do the detection on the monitor that has the primary focus at the moment... can you confirm that in your setup? Is the focus on the screen with the presentation or on the other screen? I unfortunately don't have multiple screens to test on.
Nov 5, 2014 at 6:25 AM
Yep, this is a common setup. When working a multi-monitor mode, full-screen presentation is occuring on one screen and the focus is usually on another screen with so called "presenter view". There a presenter sees running time, notes, handouts, etc. Thus in the multi-monitor environment the full-screen presentation would likely be occuring on a screen different than the one with the focus.
Nov 12, 2014 at 9:13 PM
So I looked into this a little bit more for you. There is a solution for the type of setup you're talking about but it will only work for Vista and above. This solution will not work for XP.

If the below code returns "FullScreenOrPresentationMode" or "PresentationMode", then that means that PowerPoint is presenting on one of you screens.

Let me know if this works for you. If it does, then we can perhaps think about integrating this into the toolkit as an additional check that can be performed on Vista or higher.
$UserNotificationStateSource = @'
using System;
using System.Runtime.InteropServices;
namespace QueryUser
{
    public class NotificationState
    {
        // http://msdn.microsoft.com/en-us/library/bb762533(v=vs.85).aspx
        public enum UserNotificationState
        {
            ScreenSaverOrLockedOrFastUserSwitching=1, FullScreenOrPresentationMode=2, RunningDirect3dFullScreen=3, PresentationMode=4, AcceptsNotifications=5, QuietTime=6, WindowsStoreAppRunning=7
        }
        // Only for Vista or above
        [DllImport("shell32.dll")]
        static extern int SHQueryUserNotificationState(out UserNotificationState pquns);
        public static UserNotificationState GetState()
        {
            UserNotificationState state;
            int returnVal = SHQueryUserNotificationState(out state);
            return state; 
        }
    }
}
'@
If (-not ([System.Management.Automation.PSTypeName]'QueryUser.NotificationState').Type) {
    Add-Type -TypeDefinition $UserNotificationStateSource -Language CSharp
}
Start-Sleep -Seconds 10
[QueryUser.NotificationState]::GetState()
Nov 12, 2014 at 9:29 PM
mmashwani, you're a star!!

We're looking into this one.
Dec 15, 2014 at 12:32 PM
mmashwani wrote:
So I looked into this a little bit more for you. There is a solution for the type of setup you're talking about but it will only work for Vista and above. This solution will not work for XP.

If the below code returns "FullScreenOrPresentationMode" or "PresentationMode", then that means that PowerPoint is presenting on one of you screens.

Let me know if this works for you. If it does, then we can perhaps think about integrating this into the toolkit as an additional check that can be performed on Vista or higher.
$UserNotificationStateSource = @'
using System;
using System.Runtime.InteropServices;
namespace QueryUser
{
    public class NotificationState
    {
        // http://msdn.microsoft.com/en-us/library/bb762533(v=vs.85).aspx
        public enum UserNotificationState
        {
            ScreenSaverOrLockedOrFastUserSwitching=1, FullScreenOrPresentationMode=2, RunningDirect3dFullScreen=3, PresentationMode=4, AcceptsNotifications=5, QuietTime=6, WindowsStoreAppRunning=7
        }
        // Only for Vista or above
        [DllImport("shell32.dll")]
        static extern int SHQueryUserNotificationState(out UserNotificationState pquns);
        public static UserNotificationState GetState()
        {
            UserNotificationState state;
            int returnVal = SHQueryUserNotificationState(out state);
            return state; 
        }
    }
}
'@
If (-not ([System.Management.Automation.PSTypeName]'QueryUser.NotificationState').Type) {
    Add-Type -TypeDefinition $UserNotificationStateSource -Language CSharp
}
Start-Sleep -Seconds 10
[QueryUser.NotificationState]::GetState()
Tested. Works!

Quint